[SOLVED] MIPS traps not working?

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
irvanherz
Member
Member
Posts: 27
Joined: Mon Sep 19, 2016 5:34 am

[SOLVED] MIPS traps not working?

Post by irvanherz »

Hello guys, I'm triying to develop simple hello world OS. But I get stuck in interrupt/traps handling. It seem that I miss something,
I have read MIPS32TM Architecture For Programmers Volume III: The MIPS32TM Privileged Resource Architecture. It was said that trap vector for software interrupt is 0x80000180. So, I made new section with VMA base address for interrupt handler at that address. But, why this code not working?

kernel.c

Code: Select all

/* mipsel-linux-gnu-gcc -mips32 -EL -c kernel.c -o kernel.o */
/* mipsel-linux-gnu-ld -Tscript.txt interrupt.o start.o kernel.o -o kernel.elf */
/* qemu-system-mipsel -machine mips -nographic -kernel kernel.elf */

#define R4K_MMIO_BASE 0x14000000
#define R4K_UART0_BASE (R4K_MMIO_BASE + 0x3F8)

void init_uart0() {
    *((char*)(R4K_UART0_BASE + 1)) = 0;
    *((char*)(R4K_UART0_BASE + 3)) = 0x80;
    *((char*)(R4K_UART0_BASE + 0)) = 0x03;
    *((char*)(R4K_UART0_BASE + 1)) = 0x00;
    *((char*)(R4K_UART0_BASE + 3)) = 0x03;
    *((char*)(R4K_UART0_BASE + 2)) = 0xc7;
    *((char*)(R4K_UART0_BASE + 4)) = 0x0b;
}

void print_uart0(const char *s) {
	while(*s) {
		while((*((char*)(R4K_UART0_BASE + 5)) & 0x20) == 0); //wait
		*((char*)(R4K_UART0_BASE + 0)) = *s;
		s++;
	}
}
 
void KMain() {
	init_uart0();
	print_uart0("Hello world!\n");
	//Trap if 0
	asm("teqi $zero,0");
}

//Trap 0
void Int0() {
	print_uart0("Trap say hello world!\n");
}
interrupt.s

Code: Select all

.text
	lui    	$t1, %hi(Int0)
	addiu  	$t1, %lo(Int0)
	jalr   	$t1
	eret
start.s

Code: Select all

/* mipsel-linux-gnu-gcc -mips32 -EL -c start.S -o start.o */

.global _start
_start:
	lui		$sp, %hi(STACK_TOP)
	addiu	$sp, $sp, %lo(STACK_TOP)

	# Enable interrupts in status register
	# bit 0 : Global interrupt enable flag
	# bit 8-15 : Interrupt mask. 1=enabled
	mfc0    $t0, $12
	ori 	$t0, $t0, 0xFF01
	mtc0    $t0, $12
	
	lui     $t1, %hi(KMain)
	addiu   $t1, %lo(KMain)
	jalr    $t1
	j .
script.txt

Code: Select all

ENTRY(_start)
SECTIONS
{
 . = 0x80000180;
 .interrupt : { interrupt.o(.text) }
 . = 0x80100400;
 .startup . : {start.o(.text) }
 .text : { *(.text) }
 .data : { *(.data) }
 .bss : { *(.bss COMMON) }
 . = ALIGN(8);
 . = . + 0x1000; /* 4kB of stack memory */
 STACK_TOP = .;
}
After I built and run it under qemu, "Hello world" shown up. But, nothing more. I can't see message from Int0().
Is there anything I missed?
Last edited by irvanherz on Tue Jan 03, 2017 12:39 am, edited 1 time in total.
User avatar
dchapiesky
Member
Member
Posts: 204
Joined: Sun Dec 25, 2016 1:54 am
Libera.chat IRC: dchapiesky

Re: MIPS traps not working?

Post by dchapiesky »

Could you add a loop please...

Code: Select all

void KMain() {
   init_uart0();
   print_uart0("Hello world!\n");
   //Trap if 0
   asm("teqi $zero,0");
   while(1) {}
}
I just wonder if qemu is exiting simulation before passing the interupt along to your handler....
Plagiarize. Plagiarize. Let not one line escape thine eyes...
irvanherz
Member
Member
Posts: 27
Joined: Mon Sep 19, 2016 5:34 am

Re: MIPS traps not working?

Post by irvanherz »

I just wonder if qemu is exiting simulation before passing the interupt along to your handler....
Thanks for your answer. But, finally I found that interrupt still not well prepared. So, this code work well for me

Code: Select all

/* mipsel-linux-gnu-gcc -mips32 -EL -c start.S -o start.o */
.global _start
_start:
	lui		$sp, %hi(STACK_TOP)
	addiu	$sp, $sp, %lo(STACK_TOP)

	# Enable interrupts in status register
	# bit 0 : Global interrupt enable flag
	# bit 8-15 : Interrupt mask. 1=enabled
	# bit 22 : location of interrupt vector. 0:boostrap, 1:normal
	# bit 29-32 : Coprocessor enabled flag
	mfc0    $t0, $12
	
	lui		$t1, 0xFFBF
	ori		$t1, 0xFFFF
	and		$t0, $t0, $t1
	
	lui		$t1, 0xF000
	ori 	$t1, $t1, 0xFF07
	or	 	$t0, $t0, $t1
	mtc0    $t0, $12
	
	lui     $t1, %hi(KMain)
	addiu   $t1, %lo(KMain)
	jalr    $t1
	j .

Post Reply