[SOLVED] MIPS traps not working?
Posted: Thu Dec 22, 2016 7:41 pm
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
interrupt.s
start.s
script.txt
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?
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");
}
Code: Select all
.text
lui $t1, %hi(Int0)
addiu $t1, %lo(Int0)
jalr $t1
eret
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 .
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 = .;
}
Is there anything I missed?