1. 程式人生 > >SylixOS中端模式處理方式總結

SylixOS中端模式處理方式總結

設計 硬件 如果 寄存器 分析 訪問 圖片 地址 power

1. 端模式簡介

端模式(Endian)表示數據在存儲器中的存放順序。大端模式(Big-endian),將數據的低位保存在高地址中,而數據的高位,保存在低地址中。小端模式(Little-endian),將數據的低位保存在內存的低地址中,而數據的高位保存在高地址中。

1.1 端模式對數據字節序的影響

對於內存數據字節序,大端模式高字節(MSB)存放在低地址,低字節(LSB)存放在高地址;小端模式低字節(LSB)存放在低地址,高字節(MSB)存放在高地址。如果將一個32位的整數0x12345678存放到一個整型變量(int)中,這個整型變量采用大端或者小端模式在內存中的存儲如圖 1.1所示。

技術分享圖片

圖 1.1 大小端模式在內存中的存儲

1.2 端模式對處理器寄存器的影響

對於處理器的寄存器而言大小端模式也存在區別。大端處理器,比如PowerPC,將其寄存器的最高位msb(most significant bit)定義為0,最低位lsb(least significant bit)定義為31;而小端處理器正好相反,將其寄存器的最高位定義為31,低位地址定義為0。大小端寄存器位圖區別如圖 1.2所示。

技術分享圖片

圖 1.2大小端模式CPU的寄存器位圖分布

1.3 端模式對數據總線的影響

從數據總線角度而言,大端模式下32位數據總線的msb是第0位,MSB是數據總線的第0~7的字段;而lsb是第31位,LSB是第24~31字段。小端模式下32位總線的msb是第31位,MSB是數據總線的第31~24位,lsb是第0位,LSB是7~0字段。

1.4 端模式轉換

網絡上的絕大多數協議都采用大端編址方式進行編址,因此在有關網絡協議的軟件設計中,使用小端方式的處理器需要在軟件中處理端模式的轉變。

大端處理器采用32位總線與小端外設進行訪問時,大端處理器的32位數據總線的第0~7位對應小端外設的第31~24位,第8~15位對應第23~16位,第16~23位對應第15~8位,第24~31位第7~0位。有兩種處理方式可以解決此問題:(1)在硬件上將數據線0-31和31-0進行反接;(2)從軟件上解決這個問題,在底層讀寫寄存器函數中,將讀/寫的數據進行大小端轉換。

2. SylixOS中對端模式的處理

2.1 大小端模式數據轉換

大小端模式數據轉換實際就是對字節序進行交換,以32位數據為例,轉換接口bswap32就是將高低字節進行轉換。

bswap32(uint32_t x)
{
    return  (uint32_t)((((x) & 0x000000ff) << 24) |
                       (((x) & 0x0000ff00) <<  8) |
                       (((x) & 0x00ff0000) >>  8) |
                       (((x) & 0xff000000) >> 24));
}

2.2 外設操作通用接口

SylixOS中對於大小端的操作接口與Linux做了兼容。因為普通的外設基本上都是小端模式,對外設的內存操作可以直接使用圖 2.1一組接口進行,這些操作屏蔽了大小端的差異。

技術分享圖片

圖 2.1 通用接口

以writel為例,分析下具體的實現。writel是一個宏,展開後實際上是對內存地址的寫操作,關鍵點是對要寫入的數據通過htole32進行了轉換。htole32接口通過不同CPU定義的大小端模式,判斷是否進行大小端數據轉換,如果是大端就調用bswap32進行轉換,如果是小端不轉換。

#define writel(val, addr)   write32(htole32(val), (addr_t)(addr))#define write32(d, a)      write32_raw(d, a)static LW_INLINE VOID  write32_raw (UINT32  uiData, addr_t  ulAddr){
    KN_IO_WMB();
    *(volatile UINT32 *)ulAddr = uiData;
    KN_IO_WMB();
}

2.3 外設操作特殊接口

根據不同的CPU形態還定義了一些特殊處理接口,可以指定對大小端設備的操作,具體如圖 2.2 特殊接口所示。後綴_le接口代表以小端模式操作,_be代表以大端模式操作。

技術分享圖片

圖 2.2 特殊接口

具體實現跟通用接口類似,都是根據不同CPU的大小端模式與要操作的模式是否相同,判斷是否需要進行字節序轉換。比如PPC的處理器要寫入處理器內部的寄存器,因為寄存器也是以大端模式存儲的,可以調用write32_be來實現。


SylixOS中端模式處理方式總結