Page 1 of 1

timer interrupt not come in bochs, but qemu come?

Posted: Wed Nov 14, 2007 7:44 am
by jinglexy
code take reference as linux-2.4.18,
it works well in qemu,
but timer intterrupt never run on bochs-2.3(windows and linux)
bochs config file at :
http://jinix.sourceforge.net/bochsrc.txt.linuxr


i8259 init:

Code: Select all

void CIRQ::init_8259A(int auto_eoi)
{
	UNUSED unsigned long flags;

	//spin_lock_irqsave(&i8259A_lock, flags);
	PortIO::outportb(0xff, PIC_MASTER_IMR);	/* mask all of 8259A-1 */
	PortIO::outportb(0xff, PIC_SLAVE_IMR);	/* mask all of 8259A-2 */

	/*
	 * outb_p - this has to work on a wide range of PC hardware.
	 */
	PortIO::outportb_p(0x11, PIC_MASTER_CMD);	/* ICW1: select 8259A-1 init */
	PortIO::outportb_p(0x20 + 0, PIC_MASTER_IMR);	/* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
	PortIO::outportb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR);	/* 8259A-1 (the master) has a slave on IR2 */
	if (auto_eoi)	/* master does Auto EOI */
		PortIO::outportb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR);
	else		/* master expects normal EOI */
		PortIO::outportb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR);

	PortIO::outportb_p(0x11, PIC_SLAVE_CMD);		/* ICW1: select 8259A-2 init */
	PortIO::outportb_p(0x20 + 8, PIC_SLAVE_IMR);		/* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
	PortIO::outportb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR);	/* 8259A-2 is a slave on master's IR2 */
	PortIO::outportb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR);	/* (slave's support for AEOI in flat mode is to be investigated) */

	CDelay::udelay(100);	/* wait for 8259A to initialize */ 
	PortIO::outportb(cached_21, PIC_MASTER_IMR);		/* restore master IRQ mask */
	PortIO::outportb(cached_A1, PIC_SLAVE_IMR);		/* restore slave IRQ mask */
	//spin_unlock_irqrestore(&i8259A_lock, flags);
}

timer interrupt enable at irq.setup_irq(0, &irqa);

Code: Select all

void CIRQ::enable_8259A_irq(unsigned int irq)
{
	unsigned int mask = ~(1 << irq);
	unsigned long flags;

	//spin_lock_irqsave(&i8259A_lock, flags);
	cout.flags(hex | showbase);
	cached_irq_mask &= mask;
	if (irq & 8)
		PortIO::outportb(cached_A1,PIC_SLAVE_IMR);
	else
		PortIO::outportb(cached_21,PIC_MASTER_IMR);
	//spin_unlock_irqrestore(&i8259A_lock, flags);
}

trap func:

Code: Select all

void CTrap::do_trap(UNUSED struct pt_regs * regs)
{
	static int count = 0;
#if 1
	cout.flags(hex | showbase);
	cout << "isr_num is " << regs->isr_num;
                cout << ", count is " << count++ << endl;
	PortIO::outportb(0x20, 0x20);       // send eoi
#endif
	//CKernel::syshalt();
}

Posted: Wed Nov 14, 2007 8:31 am
by Combuster
You must configure the PIT as well. You are as far as I can see depending on it having a certain state.

Posted: Wed Nov 14, 2007 6:48 pm
by jinglexy
Combuster wrote:You must configure the PIT as well. You are as far as I can see depending on it having a certain state.
hi, i have init pit already, otherwise qemu won't run success:

Code: Select all

void CIRQ::init_IRQ(void)
{
                ...... ......

	/*
	 * Set the clock to HZ Hz, we already have a valid
	 * vector now:
	 */
	PortIO::outportb_p(0x34,0x43);	/* binary, mode 2, LSB/MSB, ch 0 */
	PortIO::outportb_p(LATCH & 0xff , 0x40);	/* LSB */
	PortIO::outportb(LATCH >> 8 , 0x40);	/* MSB */
	sti();
}
anything else forgot do? thanks a lot.

Posted: Wed Nov 14, 2007 10:46 pm
by iammisc
that's not the entire pit initialization sequence. That might work if the pit is in a certain state(as mentioned before) but it isn't guaranteed to work everywhere.

Look in the wiki for more info.

Posted: Thu Nov 15, 2007 5:02 am
by jinglexy
hi, the problem resolved. CIRQ::init_8259A(), the pit doesn't init in correct sequence.
thanks