A very confusing problem with interrput.

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.
Post Reply
626788149
Member
Member
Posts: 25
Joined: Mon Oct 26, 2015 7:24 am
Location: Guilin,China

A very confusing problem with interrput.

Post by 626788149 »

I have a very big big big trouble.I have spent ten hours to figure it out .But I get nothing :( :( :(

I don't know whether it is a problem with synchronization.

I try to print strings. When call cprintf function ,it do not actually print to screen immediately,instead output to a buffer.

Just @Brendan said.http://forum.osdev.org/viewtopic.php?f=1&t=29754

If without the timer interrupt, the function cprintf works very well.

I want to use timer interrupt to flush buffer.

Once the timer interrupt occurred,the buffer is flushed.

But this process doesn't last long.

It will occur other exceptions,(e.g. debug exception, after several debug exception,will occur illegal opcode exception).

I am very confused.

All those are under the real machine.

I don't know why the timer interrupt always occur with no other code executed under the qeum or boch .

Code: Select all


void os_init_main(multiboot_info_t* m,unsigned int magic)
{
	extern char _bss_start[],_bss_end[];
	if(magic != 0x2BADB002)
		return;
	memset(_bss_start,0,_bss_end - _bss_start);
	mbd = m;
	if(m == NULL)
		return;
	init_console();
	init_mem();
	init_trap();
	init_8259A();
	timerinit();
	disable_8259A_irq(IRQ2_VECTOR);
	enable_8259A_irq(IRQ0_VECTOR);
	cons_flush(tty->p_console);
	unsigned long long i = 0;
	__asm __volatile("sti");
	for(i;;i++){
		int flage = read_eflags();
		__asm __volatile("cli");
		cprintf("%d ",i);	
		write_eflags(flage);
		//cons_flush(tty->p_console);
	}
}

Code: Select all

void foo(int i)
{
	static int j = 0;
	if(i == 32){
		__asm __volatile("movb $0x20,%al\n\toutb %al,$0x20");
		//cprintf("num %d j=%d\n",i,j);
		cons_flush(tty->p_console);	
	}else{
		cprintf("num %d addr:%x j=%d\n",i,rcr2(),j);
		cons_flush(tty->p_console);
		//while(1);
	}
	//cons_flush(tty->p_console);
	j++;
}
void init_trap()
{
	int i ;
	for(i = 0;i < 256; i++) {
		SETGATE(dp[i], 0, 0x10, trap_handlers[i], 0);
	}
	lidt(&idt_pd);
}

Code: Select all

#define TRAPHANDLER_NOEC(name, num)					\
	.globl name;							\
	.type name, @function;						\
	.align 2;							\
	name:								\
	pushl $(num);							\
	call foo;							\
	addl $4,%esp;								\
	jmp _alltraps



.text
.globl _alltraps
_alltraps:
	iret
TRAPHANDLER_NOEC(thdlr0, 0)
TRAPHANDLER_NOEC(thdlr1, 1)
TRAPHANDLER_NOEC(thdlr2, 2)
TRAPHANDLER_NOEC(thdlr3, 3)
.....
TRAPHANDLER_NOEC(thdlr255, 255)

.data
.globl trap_handlers
trap_handlers:
	.long thdlr0
         .......
        .long thdlr255

Code: Select all

void cons_flush(console_t* pcon)
{
	int i;
	static int count = 0;
	static uint32_t buf[1024*1024];

	
	int byte_per_pix = video.bpp/8;
	int Xres = video.Xres;
	int Yres = video.Yres;
	int size = Xres * Yres * byte_per_pix;
	uint32_t *where = buf;

	if (pcon->last_char - pcon->first_char >= video.numchars) {
		pcon->first_char = (pcon->last_char + video.nchars_percolum -(pcon->last_char % video.nchars_percolum)) - video.numchars;	
	} else if (pcon->last_char - pcon->first_char <= 0) {
		
		int i = (pcon->last_char + video.nchars_percolum -(pcon->last_char % video.nchars_percolum));
		pcon->first_char = CONSBUFSIZE - (video.numchars-i);	
	} else {
		//while(1);	
	}
	memset(&pcon->buffer1[pcon->last_char],0x0,4*(video.nchars_percolum -(pcon->last_char % video.nchars_percolum)));
	//video.numchars
	for(i=0;i<video.numchars;i++) {
		char ch = pcon->buffer1[(pcon->first_char+i)%CONSBUFSIZE] & 0xFF;
		int x = (i % video.nchars_percolum) * video.fontw;
		int y = (i / video.nchars_percolum) * video.fonth;
		char r = 0xFF;
		char g = 0xFF;
		char b = 0xFF;
		draw_c(buf,ch,x,y,r,g,b) ;
 	}
	
	for(i=0;i < size / 4;i++) {
		if(pcon->buffer2[i] != buf[i]) {
			pcon->buffer2[i] = buf[i];
			pcon->dispmem_addr[i] = buf[i];	
		}
	}
	
}
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: A very confusing problem with interrput.

Post by Combuster »

It will occur other exceptions,(e.g. debug exception, after several debug exception,will occur illegal opcode exception).
Chances are likely your interrupt handlers corrupt your memory.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: A very confusing problem with interrput.

Post by SpyderTL »

626788149 wrote:

Code: Select all

#define TRAPHANDLER_NOEC(name, num)               \
   .globl name;                     \
   .type name, @function;                  \
   .align 2;                     \
   name:                        \
   pushl $(num);                     \
   call foo;                     \
   addl $4,%esp;                       \
   jmp _alltraps
My guess is the "addl $4, %esp;" line.

If this instruction is meant to throw away the "error number" pushed on to the stack by the CPU, then you need to have another version of this template for interrupts that do not push a value to the stack. (i.e. with this line commented out). You can find the interrupts that push error numbers to the stack here: Exceptions

Also, perhaps on a side note, you are only sending IRQ 0 acknowledgements to the PIC. You probably need to acknowledge IRQ 1-7, and 8-16 to both PICs.

Code: Select all

if(i == 32){
      __asm __volatile("movb $0x20,%al\n\toutb %al,$0x20");
      //cprintf("num %d j=%d\n",i,j);
      cons_flush(tty->p_console);   
   }
Let us know if this helps or not.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
626788149
Member
Member
Posts: 25
Joined: Mon Oct 26, 2015 7:24 am
Location: Guilin,China

Re: A very confusing problem with interrput.

Post by 626788149 »

SpyderTL wrote:
626788149 wrote:

Code: Select all

#define TRAPHANDLER_NOEC(name, num)               \
   .globl name;                     \
   .type name, @function;                  \
   .align 2;                     \
   name:                        \
   pushl $(num);                     \
   call foo;                     \
   addl $4,%esp;                       \
   jmp _alltraps
My guess is the "addl $4, %esp;" line.

If this instruction is meant to throw away the "error number" pushed on to the stack by the CPU, then you need to have another version of this template for interrupts that do not push a value to the stack. (i.e. with this line commented out). You can find the interrupts that push error numbers to the stack here: Exceptions
Because I push a vector number on the stack( pushl $(num) ),so I need pop it out before return back and IRQ0 has no error code.



I find my problem what it is.
If i change codes to this. The problem gone.

Code: Select all

	for(i;;i++){
		__asm __volatile("cli");
		cprintf("%d \n",i);	
		__asm __volatile("sti");
	}
It seem like synchronization problem.
Interrput handler corrupt memory.

Any problem with these code?

Code: Select all

__inline uint32_t
read_eflags(void)
{
	uint32_t eflags;
	__asm __volatile("pushfl; popl %0" : "=r" (eflags));
	return eflags;
}

__inline void
write_eflags(uint32_t eflags)
{
	__asm __volatile("pushl %0; popfl" : : "r" (eflags));
}

626788149
Member
Member
Posts: 25
Joined: Mon Oct 26, 2015 7:24 am
Location: Guilin,China

Re: A very confusing problem with interrput.

Post by 626788149 »

Combuster wrote:
It will occur other exceptions,(e.g. debug exception, after several debug exception,will occur illegal opcode exception).
Chances are likely your interrupt handlers corrupt your memory.
Yes,just you said.
Post Reply