zephyriot / zephyr-issues

0 stars 0 forks source link

nios2 all sys_write* oprtations map to sys_write32 due to CPU bug #533

Closed nashif closed 8 years ago

nashif commented 8 years ago

Reported by Andrew Boie:

https://gerrit.zephyrproject.org/r/#/c/3283/ Nios II appears to have an issue with the 'stbio' instruction.

When executing this code:

0x00400848 <+136>: stbio r3,0(r2)

With these registers:

r2 0x44000c 4456460 r3 0x3 3

The memory location (which is a memory-mapped register in the NS16550 IP block) ends up with the value 0x103 instead of 0x3 as expected. Before the instruction ran, the register had 0 in it. 32-bit version doesn't seem to have this problem, use that everywhere for now.

If and when we can resolve this, revert the workaround patch.

{quote} Hi All,

I’m seeing a weird issue when I use the ‘stbio’ instruction to write an 8-bit value to a register. I think this might be a CPU bug.

I found this when enabling the Zephyr NS16550 UART driver. It does 8-bit writes to set registers, since that’s how wide they are in the datasheet. Naturally these are each actually put in 32-bit registers, but the instruction doesn’t seem to be working properly.

The issues happens when I try to set the LCR (Line Control Register):

OUTBYTE(LCR(dev), LCR_CS8 | LCR_1_STB | LCR_PDIS);

This disassembles to:

0x00400820 <+96>: ldw r2,-4(fp) 0x00400824 <+100>: ldw r2,0(r2) 0x00400828 <+104>: ldw r2,8(r2) 0x0040082c <+108>: ldw r2,0(r2) 0x00400830 <+112>: addi r2,r2,12 0x00400834 <+116>: movi r3,3 0x00400838 <+120>: stb r3,-27(fp) 0x0040083c <+124>: stw r2,-24(fp) 0x00400840 <+128>: ldw r2,-24(fp) 0x00400844 <+132>: ldbu r3,-27(fp) 0x00400848 <+136>: stbio r3,0(r2)

The code is the equivalent oif:

__builtin_stbiuo(0x44000c, 0x3)

But what I found is that the value 0x103 ended up in the register!!

To illustrate, I set a breakpoint right before the instruction and dumped registers:

Breakpoint 2, 0x00400848 in sys_write8 (addr=4456460, data=3 '\003') at /projects/zephyr2/include/arch/nios2/asm_inline_gcc.h:76 76 __builtin_stbio((void *)addr, data); (gdb) x/8fx 0x440000 0x440000: 0x00000000 0x00000000 0x00000001 0x00000000 0x440010: 0x00000000 0x00000060 0x000000f0 0x00000000 (gdb) info registers zero 0x0 0 at 0xfffffffc 4294967292 r2 0x44000c 4456460 r3 0x3 3

Recall that the assembly is:

0x00400848 <+136>: stbio r3,0(r2)

So this looks right; set the value in r3 (0x3) to the memory location at 0x44000c. Except it’s not:

(gdb) si uart_ns16550_init (dev=0x405e58 <__device_uart_ns16550_0>) at /projects/zephyr2/drivers/serial/uart_ns16550.c:324 324 mdc = MCR_OUT2 | MCR_RTS | MCR_DTR; (gdb) x/8fx 0x440000 0x440000: 0x00000000 0x00000000 0x00000001 0x00000103 0x440010: 0x00000000 0x00000060 0x000000f0 0x00000000 (gdb) info registers zero 0x0 0 at 0xfffffffc 4294967292 r2 0x44000c 4456460 r3 0x3 3

Why was it set to 0x103?? If I use “stwio” I don’t have this problem.

Andrew {quote}

(Imported from Jira ZEP-558)

nashif commented 8 years ago

by Sharron LIU:

Andrew Boie , Andrew, let you decide the priority taking severity inputs.

nashif commented 8 years ago

by Andrew Boie:

Set to 'Low'. We have a workaround. It's unclear whether this CPU bug will even get fixed.

nashif commented 7 years ago

by Mark Linkmeyer:

Fixing incorrect priority