Fixing PIT and Utilizing CPUID Features And Flags

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
TheGameMaker90
Member
Member
Posts: 83
Joined: Thu Jan 07, 2021 2:01 pm

Re: Utilizing CPUID Features And Flags

Post by TheGameMaker90 »

Octocontrabass wrote:
TheGameMaker90 wrote:

Code: Select all

	outb(0x43, 0x36);
That doesn't look like one-shot mode to me.
TheGameMaker90 wrote:Not sure i understand the question,
Okay, let's go back a bit. Why are interrupts called interrupts?
They are used to interrupt the cpu for abother task. Are you referring to rehister_interrupt_handler?

Heres my whole isr:

#include <kernel/isr.h>
#include <adamantine/aos-defs.h>
#include <kernel/system/terminal.h>
#include <kernel/system/io.h>
#include <kernel/cpu.h>

char *exception_messages[] =
{
"AOS_INTERRUPT Raised! : [Division By Zero Exception]",
"AOS_INTERRUPT Raised! : [Single-Step Interrupt Exception]",
"AOS_INTERRUPT Raised! : [Non-Maskable Interrupt Exception]",
"AOS_INTERRUPT Raised! : [Breakpoint Exception]",
"AOS_INTERRUPT Raised! : [Detected Overflow Exception]",
"AOS_INTERRUPT Raised! : [Out Of Bounds Exception]",
"AOS_INTERRUPT Raised! : [Invalid Opcode Exception]",
"AOS_INTERRUPT Raised! : [No Available Coprocessor Exception]",
"AOS_INTERRUPT Raised! : [Double Fault Exception]",
"AOS_INTERRUPT Raised! : [Coprocessor Segment Overrun Exception]",
"AOS_INTERRUPT Raised! : [Invalid TSS Exception]",
"AOS_INTERRUPT Raised! : [Segment Not Present Exception]",
"AOS_INTERRUPT Raised! : [Stack Fault Exception]",
"AOS_INTERRUPT Raised! : [General Protection Fault Exception]",
"AOS_INTERRUPT Raised! : [Page Fault Exception]",
"AOS_INTERRUPT Raised! : [Reserved Interrupt Exception]",
"AOS_INTERRUPT Raised! : [Math Fault Exception]",
"AOS_INTERRUPT Raised! : [Alignment Check Exception]",
"AOS_INTERRUPT Raised! : [Machine Check Exception]",
"AOS_INTERRUPT Raised! : [SIMD Floating-Point Exception]",
"AOS_INTERRUPT Raised! : [Virtualization Exception]",
"AOS_INTERRUPT Raised! : [Control Protection Exception]",
};

isr_t interrupt_handlers[256];
/*
static void
fault_handler(registers_t regs)
{
if (regs.int_no < 32)
{
terminal_printf("%s, int_no: 0x%X.\n", exception_messages[regs.int_no], regs.int_no);
if (regs.err_code)
{
terminal_printf("ERROR_CODE: 0x%X.\n");
cpu_halt();
}
return;
}
}*/

void
register_interrupt_handler(uint8_t n, isr_t handler)
{
interrupt_handlers[n] = handler;
}

void
isr_handler(registers_t regs)
{
if (interrupt_handlers[regs.int_no] != 0)
{
isr_t handler = interrupt_handlers[regs.int_no];
handler(regs);
}
/*else
{
fault_handler(regs);
}*/
}

void
irq_handler(registers_t regs)
{
if (regs.int_no >= 40)
{
outb(0xA0, 0x20);
}
outb(0x20, 0x20); /* EOI */

if (interrupt_handlers[regs.int_no] != 0)
{
isr_t handler = interrupt_handlers[regs.int_no];
handler(regs);
}
}
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Utilizing CPUID Features And Flags

Post by Octocontrabass »

TheGameMaker90 wrote:They are used to interrupt the cpu for abother task.
Right. So, what code is running that you want to interrupt?
TheGameMaker90 wrote:Are you referring to rehister_interrupt_handler?
No.
TheGameMaker90
Member
Member
Posts: 83
Joined: Thu Jan 07, 2021 2:01 pm

Re: Utilizing CPUID Features And Flags

Post by TheGameMaker90 »

Octocontrabass wrote:
TheGameMaker90 wrote:They are used to interrupt the cpu for abother task.
Right. So, what code is running that you want to interrupt?
TheGameMaker90 wrote:Are you referring to rehister_interrupt_handler?
No.
Well, its requesting interrupt 31 (irq0). Which would have been mapped in my idt with isr 0-31 and irq 32-47. Is that what you mean?
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Utilizing CPUID Features And Flags

Post by Octocontrabass »

No, I'm not asking about the code that runs in response to the interrupt, I'm asking about the code being interrupted.
TheGameMaker90
Member
Member
Posts: 83
Joined: Thu Jan 07, 2021 2:01 pm

Re: Utilizing CPUID Features And Flags

Post by TheGameMaker90 »

I'd refer to james Molly's tutorial for that answer... As far as i know, the interrupt is set on channel 0 of the pit, this in turn is supposed to make this work. The interrupt 33 is tied to irq0 which is supposed to trigger the pit chips internal oscillator or something to that effect.
Doctor5555
Posts: 14
Joined: Sat Oct 10, 2020 4:05 pm

Re: Utilizing CPUID Features And Flags

Post by Doctor5555 »

At the end of the kernel main function/assembly start function, what happens? Is there other code that is running continuously, or do you have a hlt loop?
thewrongchristian
Member
Member
Posts: 426
Joined: Tue Apr 03, 2018 2:44 am

Re: Utilizing CPUID Features And Flags

Post by thewrongchristian »

nexos wrote:
Ethin wrote:You need to send the EOI in the interrupt routine, not when your loading the LDT/IDT. So you'd send the EOI right after incrementing the tick counter.
Also, just a side note: you may wish to turn that tick counter into an atomic integer, especially once you get to SMP. Better to do it earlier than later though. (That's my Rust background speaking, but its generally good to use mutex/locks/atomics on static mutable variables if possible. You can wait though if you don't know how.)
Using a spinlock on a uniproccesser is one of the worst performace decisions out there. For example, T1 acquires a spinlock and gets preempted by T2 while that holding spinlock. T2 then acquires that same spinlock and sitsin its whole timeslice looping. For the timer counter, it would just be better to have a per CPU timer. I think we just got waay off topic.
If you're pre-empting code that has a spin lock, you're doing it wrong whether you're on UP or MP.

I get nervous about even calling other functions with a spin lock held, and anything protected by a spin lock should be held for the minimal amount of time. I spin lock my scheduler, device driver structures that need to communicate with interrupt handlers, and higher level synchronisation structures like mutexes, which maintain wait lists. Everything else uses the higher primitives built on top of spin locks.

And while you hold the spin lock, you should also disable interrupts, to prevent an interrupt handler also trying to get that spin lock, further reinforcing the notion that spin locks should be help for the minimal amount of time.
TheGameMaker90
Member
Member
Posts: 83
Joined: Thu Jan 07, 2021 2:01 pm

Re: Utilizing CPUID Features And Flags

Post by TheGameMaker90 »

Doctor5555 wrote:At the end of the kernel main function/assembly start function, what happens? Is there other code that is running continuously, or do you have a hlt loop?
Hmm, it has a halt instruction. To be more specific:

Code: Select all

.globl _start
.type _start @function
_start:
     mov $stack_top, %esp
     call kmain
     cli
1:  hlt
     jmp 1b
.size _start, . - _start
Funny enough, I tried jmp _start instead of the hlt and it kept refreshing, but the ticks were going up...
TheGameMaker90
Member
Member
Posts: 83
Joined: Thu Jan 07, 2021 2:01 pm

Re: Utilizing CPUID Features And Flags

Post by TheGameMaker90 »

TheGameMaker90 wrote:
Doctor5555 wrote:At the end of the kernel main function/assembly start function, what happens? Is there other code that is running continuously, or do you have a hlt loop?
Hmm, it has a halt instruction. To be more specific:

Code: Select all

.globl _start
.type _start @function
_start:
     mov $stack_top, %esp
     call kmain
     cli
1:  hlt
     jmp 1b
.size _start, . - _start
Funny enough, I tried jmp _start instead of the hlt and it kept refreshing, but the ticks were going up...
Guess what? Doctor5555, you were right. I knew it couldn't be the PIT code itself since every source I found on the internet basically did it almost the same way, plus according to the wiki on the subject, everything seemed right. It crossed my mind yesterday that it could be a problem with the bootloader, but said "nah, thast would be too simple." Instead of halting the cpu I put it in an infinite loop "jmp $" and switched to nasm assembly for the time being. Now then, we can officially call that part solved. About CPU flags now.

So basically, I can detect whether I'm using AMD or Intel already. My question pertaining to that is this: How would one check if a CPU has a specific feature based on those two manufacturers?

[Edit]:
So I was just thinking, should I actually create a new topic for the CPUID and label this solved, or should I just leave this here?
Attachments
Screenshot from 2021-01-08 14-54-11.png
Doctor5555
Posts: 14
Joined: Sat Oct 10, 2020 4:05 pm

Re: Fixing PIT and Utilizing CPUID Features And Flags

Post by Doctor5555 »

Try removing the

Code: Select all

    cli
line from _start.
If you don't already know what it does, it blocks interrupts from interrupting until the interrupt flag is restored with sti.
TheGameMaker90
Member
Member
Posts: 83
Joined: Thu Jan 07, 2021 2:01 pm

Re: Fixing PIT and Utilizing CPUID Features And Flags

Post by TheGameMaker90 »

Doctor5555 wrote:Try removing the

Code: Select all

    cli
line from _start.
If you don't already know what it does, it blocks interrupts from interrupting until the interrupt flag is restored with sti.
Yes i know about that, it seems like evet bootloader tutorial uses it. Im just setting up to make changes later :)
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Fixing PIT and Utilizing CPUID Features And Flags

Post by Octocontrabass »

TheGameMaker90 wrote:Yes i know about that, it seems like evet bootloader tutorial uses it. Im just setting up to make changes later :)
Those tutorials assume your kernel main function won't return, but James Molloy's tutorial uses a kernel main function that returns. You definitely want to use a HLT loop, though - using HLT causes the CPU to reduce its power usage and heat output. You'll notice a big difference if you're using a laptop! (There are ways to put the CPU into lower power modes, too, but you can worry about them later.)
TheGameMaker90 wrote:So basically, I can detect whether I'm using AMD or Intel already. My question pertaining to that is this: How would one check if a CPU has a specific feature based on those two manufacturers?
First, don't assume AMD and Intel are the only two options. There are several others (mostly VMs, but VIA/Centaur is still around). Fortunately, detecting most features is the same regardless of manufacturer.

Second, which feature do you want to detect?
TheGameMaker90
Member
Member
Posts: 83
Joined: Thu Jan 07, 2021 2:01 pm

Re: Fixing PIT and Utilizing CPUID Features And Flags

Post by TheGameMaker90 »

Octocontrabass wrote:
TheGameMaker90 wrote:Yes i know about that, it seems like evet bootloader tutorial uses it. Im just setting up to make changes later :)
Those tutorials assume your kernel main function won't return, but James Molloy's tutorial uses a kernel main function that returns. You definitely want to use a HLT loop, though - using HLT causes the CPU to reduce its power usage and heat output. You'll notice a big difference if you're using a laptop! (There are ways to put the CPU into lower power modes, too, but you can worry about them later.)
TheGameMaker90 wrote:So basically, I can detect whether I'm using AMD or Intel already. My question pertaining to that is this: How would one check if a CPU has a specific feature based on those two manufacturers?
First, don't assume AMD and Intel are the only two options. There are several others (mostly VMs, but VIA/Centaur is still around). Fortunately, detecting most features is the same regardless of manufacturer.

Second, which feature do you want to detect?
Ok so how would I go about that? Using hlt stops my timer from running. It only outputs the number of ticks for now, but later will likely be used for causing interrupts as it's intended.

Well, no specific feature, but a list of features. The way I picture it is a list that gets checked off depending on which manufacturer is present. I followed along with this section on the wiki: https://wiki.osdev.org/CPUID and I want to know how I would check if each of those are compatible with the current CPU. And I know there are others out there,m I can only test with what I have which is AMD (Desktop) and Intel (Laptop).
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Fixing PIT and Utilizing CPUID Features And Flags

Post by Octocontrabass »

TheGameMaker90 wrote:Using hlt stops my timer from running.
No, that was caused by CLI. Create an infinite HLT loop without CLI and it'll work fine.
TheGameMaker90 wrote:Well, no specific feature, but a list of features.
Well, lucky for you, CPUID reports most features in the form of a list already. The list is a 32-bit integer with one feature per bit, where a 1 indicates the feature is present and a 0 indicates the feature is not present. If you don't want to store the list in that format, you can convert it to something else.

But you still need to decide which features you want to detect. You don't have to detect every feature right now, you can start with one or two and add more as you go.
TheGameMaker90 wrote:The way I picture it is a list that gets checked off depending on which manufacturer is present.
Why would it depend on the manufacturer?
TheGameMaker90
Member
Member
Posts: 83
Joined: Thu Jan 07, 2021 2:01 pm

Re: Fixing PIT and Utilizing CPUID Features And Flags

Post by TheGameMaker90 »

Octocontrabass wrote:
TheGameMaker90 wrote:Using hlt stops my timer from running.
No, that was caused by CLI. Create an infinite HLT loop without CLI and it'll work fine.
TheGameMaker90 wrote:Well, no specific feature, but a list of features.
Well, lucky for you, CPUID reports most features in the form of a list already. The list is a 32-bit integer with one feature per bit, where a 1 indicates the feature is present and a 0 indicates the feature is not present. If you don't want to store the list in that format, you can convert it to something else.

But you still need to decide which features you want to detect. You don't have to detect every feature right now, you can start with one or two and add more as you go.
TheGameMaker90 wrote:The way I picture it is a list that gets checked off depending on which manufacturer is present.
Why would it depend on the manufacturer?
Well as an example, Intel only had hyper threading for a while before AMD adopted a form of it. I want to make sure that the feature is supported before it's used to avoid errors. Older CPU's might not support certain features. As such, it's my job as the programmer to catch those differences before they become erroneous. Imagine I tried to use a feature like hyper threading on a CPU that doesn't even have multithreading (I know most people these days don't have to worry about that, but still), I would have to write a workaround to ensure similar features/performance without said feature.

Also, about that "halt loop." Do you mean "jmp $"? I already have that at the end.
Here's what I put:

Code: Select all

sti  // For enabling the PIT
mov esp, stack_space
call kmain  // Tmp name for entry point
jmp $  // Loop infinitely?
If that's not what you mean, could you perhaps provide an example?
Post Reply