自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

loongarch架構介紹(三)—地址翻譯

系統(tǒng) OpenHarmony
本文介紹了地址翻譯模式以及相關的配置。下一篇文章將繼續(xù)對loongarch虛擬內(nèi)存系統(tǒng)中的其他部分。

??想了解更多關于開源的內(nèi)容,請訪問:??

??51CTO 開源基礎軟件社區(qū)??

??https://ost.51cto.com??

前言

本文是loongarch架構介紹系列的第三篇文章。前面的第一篇文章介紹了loongarch架構中的基礎指令和使用,第二篇文章介紹了內(nèi)存模型、原子指令與柵障指令的使用。

虛擬內(nèi)存系統(tǒng)是軟硬協(xié)同的一個經(jīng)典案例,如今主流的架構和操作系統(tǒng)都已經(jīng)支持虛擬內(nèi)存機制。本文介紹loongarch虛擬內(nèi)存系統(tǒng)中的地址翻譯部分,主要包括地址翻譯模式、loongarch中多級頁表和相關的配置。另外本文中許多寄存器等資源屬于特權資源,因此也會介紹loongarch中的csr特權指令和特權級作為背景知識。

一、特權級和csr特權指令

虛擬內(nèi)存相關的寄存器等資源屬于特權資源,因此在介紹loongarch虛擬內(nèi)存相關機制之前,先對loongarch中的特權指令和特權級進行介紹。

1、特權級

loongarch架構中有4個特權等級(Privilege Level,簡稱PLV),分別為PLV0-PLV3。其中PLV0的權限最高,也是唯一可以使用特權指令并訪問所有特權資源的特權等級。而PLV3的權限最低。并且PLV1-PLV3這三個特權級下大部分情況下都不能執(zhí)行特權執(zhí)行以訪問特權資源。

例如,在Linux系統(tǒng)loongarch架構相關代碼中,內(nèi)核態(tài)處于PLV0,而用戶態(tài)處于PLV3。

loongarch架構中有許多控制狀態(tài)寄存器(CSR),在loongarch資料中一般用CSR.xxx來表示某個控制狀態(tài)寄存器。cpu當前所處的特權級就由當前模式信息寄存器CSR.CRMD中的PLV域確定,即通過配置CSR.CRMD.PLV可以設置當前特權級。

2、csr特權指令

csr特權指令用于訪問和配置控制狀態(tài)寄存器,有以下幾種:

csrrd:讀取CSR。如csrrd rd, csr_num表示將csr_num對應的CSR的值寫入到通用寄存器rd中。其中csr_num為loongarch中控制狀態(tài)寄存器的編號,如CSR.CRMD對應的編號為0。

如下面代碼將CSR.CRMD中值讀到臨時寄存器t0中:

csrrd t0, 0 // CSR.CRMD對應的編號為0

csrwr:寫入CSR。如csrwr rd, csr_num表示將通用寄存器rd中的值寫入csr_num對應的CSR,同時將csr_num對應CSR中的舊值返回到rd中。

如使用下面代碼可以設置特權級為PLV3:

li.d t0, 0xXXXXXXXXXXXXXXX3 // 最低兩位為3
csrwr t0, 0

csrxchg:如csrxchg rd, rj, csr_num表示將通用寄存器rj中的值作為掩碼mask,將rd中值寫入到csr_num對應CSR中對應掩碼為1的那些比特,該CSR中的其余比特不變。同時將csr_num對應CSR中的舊值返回到rd中。

如以下代碼同樣可以設置特權級為PLV3:

li.d t0, 0x3
csrxchg t0, t0, 0 // 只將CSR.CRMD最后兩位置1

下圖為CSR.CRMD表中PLV部分描述:

# loongarch架構介紹#[三]地址翻譯-開源基礎軟件社區(qū)

二、地址空間

loongarch中的虛擬地址空間大小為:

  • LA32中虛擬地址空間大小為2^{32}232字節(jié)
  • LA64中虛擬地址空間大小為2^{64}264字節(jié)

loongarch中的物理地址空間大小為2^{PALEN}2PALEN字節(jié),其中:

  • LA32中,PALEN為一個不超過36的正整數(shù),通常為32
  • LA64中,PALEN為一個不超過60的正整數(shù)
  • PALEN由具體的實現(xiàn)決定,軟件可以通過CPUCFG指令讀取PALEN的值

三、地址翻譯模式

loongarch虛實地址轉換機制首先由其地址翻譯模式所確定。

loongarch中有兩種地址翻譯模式:

直接地址翻譯模式:在該模式下,物理地址直接等于虛擬地址的低PALEN位,不足補0。相當于沒有進行映射。

映射地址翻譯模式:在該模式下,又分為兩種模式:

  • 直接映射地址翻譯模式(簡稱直接映射模式):相當于線性映射。具體細節(jié)見后文中說明。
  • 頁表映射地址翻譯模式(簡稱頁表映射模式):相當于分頁機制。具體細節(jié)見后文中說明。

其中,直接地址翻譯模式和映射地址翻譯模式不能夠同時啟用。但在映射地址翻譯模式下,可以同時啟用直接映射模式和頁表映射模式,進行地址翻譯時,會優(yōu)先使用直接映射模式,如果無法使用直接映射模式,才會使用頁表映射模式進行翻譯。

1、地址翻譯模式的配置

loongarch中通過控制寄存器CSR.CRMD配置地址翻譯模式:

  • CSR.CRMD中DA=1且PG=0:直接地址翻譯模式
  • CSR.CRMD中DA=0且PG=1:映射地址翻譯模式
  • 其他DA和PG值的組合的行為未定義

CSR.CRMD表中DA和PG部分如下圖:

# loongarch架構介紹#[三]地址翻譯-開源基礎軟件社區(qū)

類似于上文中特權級的設置,地址翻譯模式的設置同樣使用csrwr等指令。

2、直接映射模式及其配置

loongarch中的直接映射模式是一種線性的映射方式,有點類似于分段。loongarch中通過配置直接映射配置窗口寄存器,來配置直接映射。

共有4個直接映射配置窗口寄存器,CSR.DMW0-CSR.DMW3,配置一個窗口相當于映射一段內(nèi)存區(qū)域。其中CSR.DMW0和CSR.DMW1映射的內(nèi)存區(qū)域可以同時用于取指和load/store操作,而CSR.DMW2和CSR.DMW3映射的內(nèi)存區(qū)域僅用于load/store操作。

下面對直接映射模式配置和映射規(guī)則進行說明。

(1) LA32

下面以LA32、且PALEN=32為例進行說明。

LA32中直接映射配置窗口寄存器內(nèi)容如下圖:

# loongarch架構介紹#[三]地址翻譯-開源基礎軟件社區(qū)

其中:

  • PLV0等域為使能CSR.DMW寄存器,且與訪問特權級相關
  • MAT域與內(nèi)存一致性模型和內(nèi)存訪問類型相關,可參考上一篇文章
  • PSEG域為配置的物理地址最高3位
  • VSEG域為配置的虛擬地址最高3位

例如,以下代碼配置CSR.DMW0,將虛擬地址0x80000000-0x9fffffff映射到物理地址0x0-0x1fffffff:

li.w t0, 0x80000011
csrwr t0, 0x180 // 0x180對應CSR.DMW0

解釋如下:

  • 0x80000011中,VSEG為0b100,表示匹配的虛擬地址的最高3位為0b100,即虛擬地址0x80000000-0x9fffffff
  • 0x80000011中,PSEG為0b0,表示匹配的物理地址的最高3位為0b0,即對應物理地址0x0-0x1fffffff

(2)LA64

下面以LA64、且PALEN=48為例進行說明。

LA64中直接映射配置窗口寄存器內(nèi)容如下圖:

# loongarch架構介紹#[三]地址翻譯-開源基礎軟件社區(qū)

其中:

  • PLV0等域、MAT域與LA32中作用相同
  • VSEG域與LA32中類似,但是有4位

例如,以下代碼配置CSR.DMW0,將虛擬地址0x9000000000000000-0x9000ffffffffffff映射到物理地址0x0-0xffffffffffff:

li.d t0, 0x9000000000000011
csrwr t0, 0x180 // 0x180對應CSR.DMW0

解釋如下:

  • 0x9000000000000011中,VSEG為0x9,表示匹配的虛擬地址的最高4位為0x9,即虛擬地址0x9000000000000000-0x9000ffffffffffff
  • PALEN=48,對應的物理地址為整個2^{48}248大小的地址范圍,即0x0-0xffffffffffff

3、頁表映射模式及其配置

(1)頁表基址

在開啟頁表映射模式之后,首先需要配置頁表基址。

loongarch中可以同時有兩個pgd(頁全局目錄)基址,地址分別存儲于寄存器CSR.PGDL(低半地址空間全局目錄基址)和CSR.PGDH(高半地址空間全局目錄基址),分別對應低半地址空間和高半地址空間。CSR.PGDL和CSR.PGDH如下圖:

# loongarch架構介紹#[三]地址翻譯-開源基礎軟件社區(qū)

# loongarch架構介紹#[三]地址翻譯-開源基礎軟件社區(qū)

上圖中,GRLEN表示寄存器長度,VALEN表示虛擬地址長度。LA32中GRLEN為32,VALEN為32;LA64中GRLEN為64,VALEN為64。

低半地址空間和高半地址空間實際上就是對虛擬地址空間對半分成了兩個部分。虛擬地址最高位為0則表示處于低半地址空間;為1則表示處于高半地址空間。兩個部分的地址都用對應部分的pgd進行地址轉換,互不干擾。

在Linux中,CSR.PGDH存放內(nèi)核進程的pgd,CSR.PGDL中存放用戶進程的pgd。loongarch中相當于在硬件上又對內(nèi)核空間和用戶空間的頁表進行了隔離。

(2)頁表分級

loongarch中可以自定義頁表的分級,使用頁表前需要配置頁表分級。

loongarch中頁表的具體分級由寄存器CSR.PWCL和CSR.PWCH決定,這兩個寄存器分別控制低半部分和高半部分的頁表分級,其中CSR.PWCH只存在于LA64。注:這里的低半部分和高半部分指的是寄存器分成了兩部分。CSR.PWCL和CSR.PWCH分別如下圖:

# loongarch架構介紹#[三]地址翻譯-開源基礎軟件社區(qū)

# loongarch架構介紹#[三]地址翻譯-開源基礎軟件社區(qū)

下圖是一個多級頁表的示例:

# loongarch架構介紹#[三]地址翻譯-開源基礎軟件社區(qū)

解釋如下:

其中xxbase表示該級在虛擬地址中的起始位置,xxwidth表示該級在虛擬地址中的長度

以LA64為例,配置Dir4_base、PTbase等域和Dir4_width、PTwidth等域,相當于指定了虛擬地址按分級頁表規(guī)則的解析方式

虛擬地址的解析過程示例如下:

  1. 首先根據(jù)最高位選擇CSR.PGDH或CSR.PGDL中的pgd,即目錄4的基址
  2. 將虛擬地址中Dir4_base和Dir4_width指定范圍的值作為索引,在目錄4查找對應目錄3的基址
  3. 將虛擬地址中Dir3_base和Dir3_width指定范圍的值作為索引,在目錄3查找對應目錄2的基址
  4. 將虛擬地址中Dir2_base和Dir2_width指定范圍的值作為索引,在目錄2查找對應目錄1的基址
  5. 將虛擬地址中Dir1_base和Dir1_width指定范圍的值作為索引,在目錄1查找對應末級頁表的基址
  6. 將虛擬地址中PTbase和PTwidth指定范圍的值作為索引,在末級頁表中查找最終頁表項

其中具體頁表項相關信息見后續(xù)文章。

(3)配置

本小節(jié)以Linux源碼中l(wèi)oongarch下頁表基址和分級的配置進行分析。

代碼如下:

static void setup_ptwalker(void)
{
unsigned long pwctl0, pwctl1;
unsigned long pgd_i = 0, pgd_w = 0; // Dir3_base和Dir3_width
unsigned long pud_i = 0, pud_w = 0; // Dir2_base和Dir2_width
unsigned long pmd_i = 0, pmd_w = 0; // Dir1_base和Dir1_width
unsigned long pte_i = 0, pte_w = 0; // PTbase和PTwidth
// PTEWidth為0,表示每個表項為64bit
// Dir4_base和Dir4_width未設置
pgd_i = PGDIR_SHIFT;
pgd_w = PAGE_SHIFT - 3;
#if CONFIG_PGTABLE_LEVELS > 3
pud_i = PUD_SHIFT;
pud_w = PAGE_SHIFT - 3;
#endif
#if CONFIG_PGTABLE_LEVELS > 2
pmd_i = PMD_SHIFT;
pmd_w = PAGE_SHIFT - 3;
#endif
pte_i = PAGE_SHIFT;
pte_w = PAGE_SHIFT - 3;
pwctl0 = pte_i | pte_w << 5 | pmd_i << 10 | pmd_w << 15 |
pud_i << 20 | pud_w << 25;
pwctl1 = pgd_i | pgd_w << 6;
// 設置CSR.PWCL和CSR.PWCH,LOONGARCH_CSR_PWCTL0為CSR.PWCL
// LOONGARCH_CSR_PWCTL1為CSR.PWCH
csr_write64(pwctl0, LOONGARCH_CSR_PWCTL0);
csr_write64(pwctl1, LOONGARCH_CSR_PWCTL1);
// 設置CSR.PGDL和CSR.PGDH
// CSR.PGDH中swapper_pg_dir為內(nèi)核空間pgd
// CSR.PGDL為用戶空間pgd,暫時設置為invalid_pg_dir,到進程創(chuàng)建等操作時分配
csr_write64((long)swapper_pg_dir, LOONGARCH_CSR_PGDH);
csr_write64((long)invalid_pg_dir, LOONGARCH_CSR_PGDL);
...
}

總結

本文介紹了地址翻譯模式以及相關的配置。下一篇文章將繼續(xù)對loongarch虛擬內(nèi)存系統(tǒng)中的其他部分。

??想了解更多關于開源的內(nèi)容,請訪問:??

??51CTO 開源基礎軟件社區(qū)??

??https://ost.51cto.com??

責任編輯:jianghua 來源: 51CTO 開源基礎軟件社區(qū)
點贊
收藏

51CTO技術棧公眾號