apache / apache/nuttx

[HELP] Nuttx porting: Unexpected exception vector in MIPS32

Open
#19,017 4 comments 0 reactions 0 assignees View on GitHub
Community: Question
Dominant language
C
Stars
4k
Forks
1.7k
Avg merge
1d 17h
Merged PRs (30d)
237

Description

### Description

I am porting nuttx to a MIPS32 SOC system, where there is 32MB DRAM.
I started porting by referring to the pic32mz.
First of all I want to setup interrupt and exception handlers for it, per MIPS ISA, I clear the BEV in status register and set IV in cause register of CP0, I would use 0x80000180 and 0x80000200 for exception and interrupt handling. So I worked out a board.ld as follows,
```
OUTPUT_FORMAT("elf32-tradlittlemips")
OUTPUT_ARCH(mips)
ENTRY(__start)

MEMORY
{
ram (rwx) : ORIGIN = 0x80100000, LENGTH = 31M
ramv (rwx) : ORIGIN = 0x80000000, LENGTH = 16K
}

SECTIONS
{
.start : {
*(.start)
} > ram

.vectors_load : {
_vectors_load_start = .;

. = ALIGN(4);
KEEP(*(.reset))
. = _vectors_load_start + 0x180;

. = ALIGN(4);
KEEP(*(.gen_excpt))
. = _vectors_load_start + 0x200;

. = ALIGN(4);
KEEP(*(.ebase_excpt))
. = _vectors_load_start + 0x300;

. = ALIGN(4);
KEEP(*(.cache_excpt))
. = _vectors_load_start + 0x380;

. = ALIGN(4);
KEEP(*(.bev_excpt))
. = _vectors_load_start + 0x400;

. = ALIGN(4);
KEEP(*(.int_excpt))
. = _vectors_load_start + 0x480;

. = ALIGN(4);
KEEP(*(.dbg_excpt))
. = _vectors_load_start + 0x500;

_vectors_load_end = .;
} > ramv

.text : {
_stext = .;
*(.text .text.*)
......
}
```
which defined the entry point (__start) is at 0x80100000, and the vectors are all in 0x80000N00.
From the following in nuttx.map I think the vectors are in the right location specified by board.ld.

```
Memory Configuration

Name Origin Length Attributes
ram 0x0000000080100000 0x0000000001f00000 xrw
ramv 0x0000000080000000 0x0000000000004000 xrw
*default* 0x0000000000000000 0xffffffffffffffff

Linker script and memory map

.start 0x0000000080100000 0x178
*(.start)
.start 0x0000000080100000 0x178 my_head.o
0x0000000080100000 __start

.vectors_load 0x0000000080000000 0x500
0x0000000080000000 _vectors_load_start = .
0x0000000080000000 . = ALIGN (0x4)
*(.reset)
.reset 0x0000000080000000 0x10 my_head.o
0x0000000080000000 __reset
0x0000000080000180 . = (_vectors_load_start + 0x180)
*fill* 0x0000000080000010 0x170
0x0000000080000180 . = ALIGN (0x4)
*(.gen_excpt)
.gen_excpt 0x0000000080000180 0x10 my_head.o
0x0000000080000200 . = (_vectors_load_start + 0x200)
*fill* 0x0000000080000190 0x70
0x0000000080000200 . = ALIGN (0x4)
*(.ebase_excpt)
.ebase_excpt 0x0000000080000200 0x10 my_head.o
0x0000000080000300 . = (_vectors_load_start + 0x300)
*fill* 0x0000000080000210 0xf0
0x0000000080000300 . = ALIGN (0x4)
*(.cache_excpt)
0x0000000080000380 . = (_vectors_load_start + 0x380)
*fill* 0x0000000080000300 0x80
0x0000000080000380 . = ALIGN (0x4)
*(.bev_excpt)
.bev_excpt 0x0000000080000380 0x10 my_head.o
0x0000000080000400 . = (_vectors_load_start + 0x400)
*fill* 0x0000000080000390 0x70
0x0000000080000400 . = ALIGN (0x4)
*(.int_excpt)
.int_excpt 0x0000000080000400 0x10 my_head.o
0x0000000080000480 . = (_vectors_load_start + 0x480)
*fill* 0x0000000080000410 0x70
0x0000000080000480 . = ALIGN (0x4)
*(.dbg_excpt)
0x0000000080000500 . = (_vectors_load_start + 0x500)
*fill* 0x0000000080000480 0x80
0x0000000080000500 _vectors_load_end = .

.text 0x0000000080100180 0x51260
0x0000000080100180 _stext = .
*(.text .text.*)

```
Here is the codes to setup interrupt and exception (there is an interrupt controller in SOC, so far I only enabled SW0 in status register as PIC32MZ does).
```
cp0_putebase(0x80000000);

/* Set the INTCTL vector spacing to non-zero */

cp0_putintctl(0x00000020);

/* Set the IV bit in the CAUSE register */

regval = cp0_getcause();
regval |= CP0_CAUSE_IV;
cp0_putcause(regval);

/* Clear the EXL and BEV bits in the STATUS register */
regval = cp0_getstatus();
regval &= ~(CP0_STATUS_EXL | CP0_STATUS_BEV);
cp0_putstatus(regval);

__asm__ volatile(
"sync\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
);
```
With JTAG and GDB, I loaded my image to 0x80000000 (so the vectors are well populated), I started running the image from 0x80100000.

To my surprise, I hit the codes in _bev_exception at 0x80000380 instead of 0x80000200 when the interrupt is enabled through status register, which caused no calling of interrupt handler!

I checked the cause and status registers of CP0, when _bev_exception is called, they are,

status: 00000303; cause: 40808100, there seemed be interrupt but why it is trapped to _bev_exception instead of 0x80000200?

### Verification

- [x] I have verified before submitting the report.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.