Closed nashif closed 8 years ago
by Sharron LIU:
Andrew Boie , Andrew, let you decide the priority taking severity inputs.
by Andrew Boie:
Set to 'Low'. We have a workaround. It's unclear whether this CPU bug will even get fixed.
by Mark Linkmeyer:
Fixing incorrect priority
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)