Data Abort on A20 SoC

0

I'm trying to write a small application which shows a message through Serial Port. This binary is being executed without OS, so it's bare metal.

The code is as follows:

#include <stdint.h>
#define FIFO 0x0
#define NOFIFO 0x1
#define FIFO_STATUS 0x0

#define THR_READY 0x1
#define THR_STATUS 0x5

#define UART_MEM        0x1C28000


volatile unsigned int *uart0 = (unsigned int *)UART_MEM;
volatile unsigned int *uart_str = (unsigned int *)(UART_MEM + 0x7c);
volatile unsigned int *uart_lstr = (unsigned int *)(UART_MEM + 0x14);


void print_smth(const char *str) {
    while (*str != '\0') {
            while ((*uart_lstr & (1 << THR_STATUS)) != THR_READY)
                    ;
            *uart0 = (unsigned int)(*str);
            str++;
    }
}

void c_entry(void) {
    print_smth("Hello");
}

I'm booting this binary with u-boot, and actually the binary boots fine, until it reaches:

*uart0 = (unsigned int)(*str);

Once I try to write to this memory, I get a Data Abort Error. It looks like I'm not allow to write at this memory address, but taking a look at the A20 User Manual I see that actually UART0 is being mapped to 0x01C28000, so I should have access for writing there.

This is the output:

=> loadx
## Ready for binary (xmodem) download to 0x42000000 at 115200 bps...                                                                                          
CxyzModem - CRC mode, 2(SOH)/0(STX)/0(CAN) packets, 2 retries
## Total Size      = 0x000000c4 = 196 Bytes
=>  go 0x42000000
## Starting application at 0x42000000 ...
data abort
pc : [<4200007c>]          lr : [<420000ac>]
reloc pc : [<0d0a207c>]    lr : [<0d0a20ac>]
sp : 000010b0  ip : 7fe79000     fp : 000010bc
r10: 00000002  r9 : 7af3dee0     r8 : 7efb47a8
r7 : 7af3fab8  r6 : 42000000     r5 : 00000002  r4 : 7af3fabc
r3 : ee070f15  r2 : 0000001e     r1 : 7af3fabc  r0 : 000000b0
Flags: nZCv  IRQs off  FIQs off  Mode SVC_32
Resetting CPU ...

resetting ...

Do you an idea why this is happening?

Is possible that the code is not being mapped to the RAM and this is why I'm getting this error?

== UPDATE ==

After define the vars as a constant now is working "better". It's still not working fine because I get trash instead of my text.

Here is the code updated:

#include <stdint.h>

#define TEMT_STATUS (0x1 << 6)

#define UART0   0x1C28000
    #define UART_LSR        0x14



volatile unsigned int *const uart0 = (unsigned int *)(UART0);
volatile unsigned int *const uart_lsr = (unsigned int *)(UART0 + UART_LSR);


void print_smth(const char *str) {

    while (*str != '\0') {
            while ( !(*uart_lsr & TEMT_STATUS))
                    ;
            *uart0 = (unsigned int)(*str);
            str++;
    }
}

void c_entry(void) {
    print_smth("os");
}

And the output is:

=>  go 0x42000000
## Starting application at 0x42000000 ...
��ᚕ��
    ��

I'm sure I'm missing something but I'm not sure what. I took a look at the driver which is being used by u-boot, located at:

arch/arm/cpu/armv7/sunxi/early_print.c

And actually it's not doing more than me. So I'm wondering where is the failure.

Thanks in advance Regards

c
arm
uart
u-boot
asked on Stack Overflow Aug 11, 2016 by leberus • edited Aug 12, 2016 by leberus

1 Answer

2

The most likely answer here is that you aren't building a bare metal application correctly. Please look at the hello_world example in U-Boot under examples/standalone for how to most importantly link an application. You may wish to start out by calling some of the exported functions just to confirm that you've gotten over these hurdles before you move on to whacking the hardware directly.

answered on Stack Overflow Aug 11, 2016 by Tom Rini

User contributions licensed under CC BY-SA 3.0