zynqでソートされていないメモリにアクセスするときのバスエラー

zynqでソートされていないメモリにアクセスするときのバスエラー

編集:これをより良いスタック交換サイトにアップロードする必要がありますか?

私は特にザイリンクス開発ボードzcu102でzynqハイパースケールチップのFPGA側に接続されたDDR4を使用しようとしています。私はVivadoのMIGを使用してコントローラを作成し、それをメインプロセッサのHPM0 AXIポートに接続しています。メモリ長は0x2000_0000で、物理アドレス0x4_0000_0000にマッピングされます。

私が持っている問題は、ソートされていないメモリにアクセスするときです。デバイスツリーの詳細が不足しているため、MMUの設定が間違っていると思います。

私が知っていることの1つは、このアーム(A53)が必要な場合は、ソートされていないアクセスをメモリへの複数のアクセスに切り替えることができることです。 MMUが何らかの方法で誤って設定されているというバスエラーが発生しますが、どうなるかはわかりません。

デバイスツリーが長すぎてここに入れるには長すぎて私が最も重要だと思う部分はここに直接入れ、残りは次のように入れました。ペーストビン

    amba_pl@0 {
            #address-cells = <0x2>;
            #size-cells = <0x2>;
            compatible = "simple-bus";
            ranges;

            ddr4@400000000 {
                    compatible = "xlnx,ddr4-2.2";
                    reg = <0x4 0x0 0x0 0x20000000>;
                    alignment = <0x10>;
            };

            PERIPHERAL@ff380000 {
                    compatible = "xlnx,PERIPHERAL-1.0";
                    reg = <0x0 0xff380000 0x0 0x80000>;
            };

            PERIPHERAL@ff990000 {
                    compatible = "xlnx,PERIPHERAL-1.0";
                    reg = <0x0 0xff990000 0x0 0x10000>;
            };
    };

    aliases {
            ethernet0 = "/amba/ethernet@ff0e0000";
            i2c0 = "/amba/i2c@ff020000";
            i2c1 = "/amba/i2c@ff030000";
            serial0 = "/amba/serial@ff000000";
            serial1 = "/amba/serial@ff010000";
            spi0 = "/amba/spi@ff0f0000";
    };

    memory {
            #address-cells = <0x2>;
            #size-cells = <0x2>;
            device_type = "memory";
            alignment = <0x10>;
            reg = <0x4 0x0 0x0 0x20000000>;
    };

/ memoryと/ amba_plの両方でddrコントローラのソート設定を試しましたが、違いはないようです。実際、/ memory部分はまだFPGAのメモリではなく基本システムメモリから起動するため、無視しているようです。

次のように、mmapとdevmemを使用してメモリにアクセスできます。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdint.h>
#include <math.h>

#define ARRAY_TYPE uint16_t

int main(int argc, char *argv[]) {
    if (argc != 2){
        printf("Wrong arg count\n");
        return -1;
    }
    volatile ARRAY_TYPE * ps = malloc(sizeof(ARRAY_TYPE)*10);
    if (NULL==ps){
        printf("Failed to malloc for ps\n");
        return -1;
    }


    int fd = open("/dev/mem", O_RDWR | O_SYNC );
    volatile ARRAY_TYPE *pl = mmap((void*)0x400000000, 0x20000000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x400000000);
    if (pl == MAP_FAILED) {
        perror("Can't map memory for pl");
        printf("FAIL\n");
        return -1;
    }


    //force them out of alignment by argv[1] bytes.
    volatile ARRAY_TYPE *ps_unaligned = (volatile ARRAY_TYPE *)(((uint8_t *)ps) + atoi(argv[1]));
    volatile ARRAY_TYPE *pl_unaligned = (volatile ARRAY_TYPE *)(((uint8_t *)pl) + atoi(argv[1]));

    printf("trying ps with offset %d\n", atoi(argv[1]));
    ps_unaligned[0] = 1;
    printf("trying pl with offset %d\n", atoi(argv[1]));
    pl_unaligned[0] = 1;

    munmap(pl, 0x20000000);
    free(ps);
    close(fd);

    return 0;
}

プライマリシステムメモリと整列していないメモリにアクセスしようとするたびに正常に動作します。ただし、ソートされていないFPGAから静止メモリにアクセスすると、バスエラーが発生します。

root@zynq: ~
17:22:08 $ ./memtest 0
trying ps with offset 0
trying pl with offset 0
root@zynq: ~
17:22:12 $ ./memtest 1 
trying ps with offset 1
trying pl with offset 1
Bus error
root@zynq: ~
17:22:13 $ ./memtest 2
trying ps with offset 2
trying pl with offset 2
root@zynq: ~
17:22:14 $ ./memtest 3
trying ps with offset 3
trying pl with offset 3
Bus error

また、gdbセッション中に/ proc / $ pid / smapsをチェックして、メモリ領域の仮想メモリマップを調べました。これは、devmem / mmapを使用して割り当てられたシステムメモリを含むセクションです。

400000000-420000000 rw-s 400000000 00:06 1054                            /dev/mem
Size:             524288 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                   0 kB
Pss:                   0 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:            0 kB
Anonymous:             0 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                  0 kB
SwapPss:               0 kB
Locked:                0 kB
VmFlags: rd wr sh mr mw me ms pf io de dd 

以下は、FPGAによってマッピングされたメモリの一部です。

5555567000-5555588000 rw-p 00000000 00:00 0                              [heap]
Size:                132 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                   4 kB
Pss:                   4 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         4 kB
Referenced:            4 kB
Anonymous:             4 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                  0 kB
SwapPss:               0 kB
Locked:                0 kB
VmFlags: rd wr mr mw me ac 

フラグの違いが何が起こっているのか説明するのかは分かりませんが、メモリマッピングにもっと精通した人が何かを知っている場合を備えて含めています。

ベストアンサー1

おすすめ記事