2014-09-29 36 views
5

Próbowałem uruchomić aplikację RTEMS (aplikacja działająca w czasie rzeczywistym) na maszynie wirtualnej sparc przy użyciu QEMU. Już prawie jestem i widziałem to kilka godzin temu. Ale po usunięciu niektórych wydruków nie działa, a później okazało się, że to nie z powodu usuniętych wydruków. Dane nie są poprawnie przesyłane między obrazem RTEMS a modelem emulacji QEMU. (Pracuję z QEMU w wersji 1.5.50 i modelem lan9118.c zapożyczonym z QEMU w wersji 2.0.0. Modyfikuję lan9118.)
w modelu QEMU, OPS obszaru pamięci są zdefiniowane jakoWartość zapisu procesora przekazana z aplikacji do qemu jest dziwna

struct MemoryRegionOps { 
    /* Read from the memory region. @addr is relative to @mr; @size is 
    * in bytes. */ 
    uint64_t (*read)(void *opaque, 
        hwaddr addr, 
        unsigned size); 
    /* Write to the memory region. @addr is relative to @mr; @size is 
    * in bytes. */ 
    void (*write)(void *opaque, 
        hwaddr addr, 
        uint64_t data, 
        unsigned size); 
... 
} 

oraz w aplikacji rtems, piszę do urządzenia jak

 *TX_FIFO_PORT = cmdA; 
     *TX_FIFO_PORT = cmdB; 

gdzie TX_FIFO_PORT jest zdefiniowany jako poniżej.

#define TX_FIFO_PORT     (volatile ulong *)(SMSC9118_BASE + 0x20) 

Ale kiedy piszę, na przykład,

cmdA : 0x2a300200 and cmdB : 0x2a002a00, 

Wartości ja oczekiwane są

cmdA : 0x0002302a and cmdB : 0x002a002a. (Just endian converted values) 

ale wartości, które widzę w funkcji write (wejście od QEMU) są

cmdA : 0x02000200 and cmdB : 0x2a002a00 respectively. 

Obserwowane wartości h ave nie została przekształcona na endian i nawet pierwsza wartość jest inna (powtórzono 16-bitowe powtórzenie). Co może być problemem?
Każda wskazówka zostanie doceniona.

+0

Jeśli nagle zostaną uszkodzone dane podczas dodawania/usuwania niepowiązanych funkcji, prawdopodobnie występuje przepełnienie stosu. – Lundin

+0

W QEMU, każdy model urządzenia zapewnia funkcję zapisu i odczytu, a także określa, w jaki sposób słowo powinno zostać przekazane do/z urządzenia w odniesieniu do endianness. Jest określony jak poniżej.'static const MemoryRegionOps lan9118_mem_ops = { .read = lan9118_readl, .write = lan9118_writel, .endianness = DEVICE_NATIVE_ENDIAN, };' ' –

Odpowiedz

0

Co dziwne, naprawiłem to, komentując konwersję endianów dla cmdA i cmdB w RTEMS przed zapisaniem na urządzeniu. (Nie było problemu z konwersją endianów. Nie wiem) Więc działa prawie ". W każdym razie, tutaj jest wskazówka dotycząca wymiany danych zapisu/odczytu CPU w procesorze QEMU i deivce.
W QEMU, każdy model urządzenia zapewnia funkcję zapisu i odczytu, a także określa, w jaki sposób słowo powinno zostać przekazane do/z urządzenia w odniesieniu do endianness. Jest określony jak poniżej.

static const MemoryRegionOps lan9118_mem_ops = { 
    .read = lan9118_readl, 
    .write = lan9118_writel, 
    .endianness = DEVICE_NATIVE_ENDIAN, 
}; 

Oto kopia z elektroniczną otrzymałem od Peter Meydell z [email protected] listy.

------------------------

To zależy od tego, co struct MemoryRegionOps dla regionu pamięci ustawia .endianness boiska. DEVICE_NATIVE_ENDIAN oznacza, że ​​urządzenie widzi wartości w ten sam sposób, co natywna endianness procesora gościa [*], więc jeśli gość wykonuje 32-bitowy zapis 0x12345678, pojawia się on w argumencie funkcji zapisu jako 0x12345678. DEVICE_BIG_ENDIAN oznacza, że ​​jeśli CPU jest małym endianem, to słowo zostanie pominięte. DEVICE_LITTLE_ENDIAN oznacza, że ​​jeśli procesor jest duży endian, to słowo zostanie pominięte. Te ostatnie są użyteczne dla urządzeń lub magistrali, które mają specyficzną endogeniczność, która nie jest taka sama jak w CPU (np. PCI jest zawsze małym endianem).