教育網(wǎng)站如何做seo網(wǎng)絡(luò)運(yùn)營(yíng)團(tuán)隊(duì)
目錄
一、CP0概述
1.1 CP0概述
1.2?龍芯異常exception與中斷interrupt的區(qū)別
二、CPU協(xié)處理器的異常處理
三、外部中斷與外部中斷控制器
3.1 外部中斷源
3.2 如何配置外部中斷源
3.3 外部中斷的中斷向量表
3.2.1 軟件中斷向量表結(jié)構(gòu)定義:ls1b_irq.c
3.2.2 軟件中斷向量表定義:ls1b_irq.c和ls1b_irq.h
3.3.3 默認(rèn)的中斷處理或中斷服務(wù)程序:ls1b_irq.c
3.3.4 中斷向量表的初始化
3.3.5 安裝用戶自定義的中斷服務(wù)程序的安裝與移除
一、CP0概述
1.1 CP0概述
龍芯1B協(xié)處理器CP0(Coprocessor 0)是龍芯處理器(Loongson)中的一個(gè)重要組成部分,主要用于管理處理器的系統(tǒng)級(jí)行為和狀態(tài)信息。CP0是一個(gè)與主處理器CPU緊密集成的協(xié)處理器,它的功能主要有以下幾個(gè)方面:
-
地址轉(zhuǎn)換和虛擬存儲(chǔ)管理MMU:CP0可以實(shí)現(xiàn)物理地址的解析和轉(zhuǎn)換,支持虛擬存儲(chǔ)管理,使得應(yīng)用程序可以像訪問(wèn)物理內(nèi)存一樣方便地訪問(wèn)虛擬內(nèi)存區(qū)域。
-
異常和中斷處理(本文要深入討論的部分):CP0是處理器內(nèi)部異常exception和外部中斷Interrupt處理的核心,它存儲(chǔ)了異常和中斷向量表、錯(cuò)誤狀態(tài)碼等信息,并負(fù)責(zé)中斷的響應(yīng)和異常處理程序的執(zhí)行。
-
性能計(jì)數(shù)器和性能分析:CP0中還包括可編程的性能計(jì)數(shù)器和時(shí)鐘戳記寄存器,可以用于對(duì)程序的性能分析和調(diào)優(yōu),并支持操作系統(tǒng)的性能監(jiān)控功能。
-
系統(tǒng)控制寄存器:CP0中還包含了一些系統(tǒng)級(jí)別的控制寄存器,可以用于修改處理器的運(yùn)行狀態(tài),如設(shè)置緩存策略、開(kāi)/關(guān)寫(xiě)緩沖等。
總之,龍芯1B協(xié)處理器CP0是Loongson處理器的重要組成部分,它管理和控制處理器中的系統(tǒng)級(jí)行為和狀態(tài)信息,為操作系統(tǒng)和應(yīng)用程序提供了重要的支持和保障。
1.2?龍芯異常exception與中斷interrupt的區(qū)別
龍芯處理器中的異常(exception)和中斷(interrupt)在概念上是有區(qū)別的,它們分別代表了不同類型的事件和處理機(jī)制:
-
異常(Exception):異常是指在程序執(zhí)行過(guò)程中出現(xiàn)的一種非正常事件,通常是由指令執(zhí)行時(shí)產(chǎn)生的,可以看作是處理器內(nèi)部的問(wèn)題。異??梢允且?yàn)?span style="color:#fe2c24;">錯(cuò)誤的操作碼、內(nèi)存訪問(wèn)沖突、算術(shù)錯(cuò)誤等原因?qū)е碌?#xff0c;需要處理器暫停當(dāng)前指令的執(zhí)行并執(zhí)行相應(yīng)的異常處理程序。異常通常由處理器本身或者處理器內(nèi)部邏輯主動(dòng)觸發(fā),它跳轉(zhuǎn)到異常處理程序,處理完異常后再恢復(fù)到正常指令流程。
-
中斷(Interrupt):中斷是指來(lái)自外部設(shè)備的一種請(qǐng)求,要求處理器暫停當(dāng)前正在執(zhí)行的程序,轉(zhuǎn)而執(zhí)行與中斷相關(guān)的處理程序。中斷是處理器響應(yīng)外部事件的一種方式,可以是來(lái)自設(shè)備的信號(hào)或者時(shí)鐘,需要處理器打斷當(dāng)前執(zhí)行的指令流程,執(zhí)行相應(yīng)的中斷服務(wù)程序,處理完中斷后再返回到被中斷的程序繼續(xù)執(zhí)行。
????????在龍芯處理器中,異常和中斷的區(qū)別在于觸發(fā)原因和處理方式上:異常通常是由指令執(zhí)行過(guò)程中的內(nèi)部錯(cuò)誤或意外情況引發(fā),需要處理器內(nèi)部去處理;而中斷是由外部事件觸發(fā),需要處理器響應(yīng)外部設(shè)備的請(qǐng)求。處理器在接收到異?;蛑袛嘈盘?hào)后,會(huì)根據(jù)具體情況執(zhí)行相應(yīng)的處理程序,保證系統(tǒng)的穩(wěn)定運(yùn)行和正確性。
二、CPU協(xié)處理器的異常處理
三、外部中斷與外部中斷控制器
3.1 外部中斷源
龍芯1B SOC芯片內(nèi)置簡(jiǎn)單、靈活的中斷控制器。
1B芯片的中斷控制器除了管理 GPIO輸入的中斷信號(hào)外,中斷控制器還處理內(nèi)部設(shè)備引起的中斷。所有的中斷寄存器的位域安排相同,一個(gè)中斷源對(duì)應(yīng)其中一位。
SOC的中斷控制器共四個(gè)中斷線輸出連接到CPU模塊,分別對(duì)應(yīng) INT0, INT1, INT2, INT3。
SOC芯片中斷控制器本身能夠支持 64個(gè)內(nèi)部中斷和 64個(gè) GPIO的中斷,最大一共128個(gè)硬件外部中斷源,這128個(gè)中斷源分為四組,每組最大支持32個(gè)中斷源,分別歸組為:INT0, INT1, INT2, INT3。
其中 INT0和 INT1分別對(duì)應(yīng)于 64個(gè)內(nèi)部中斷的前后 32位,INT2和 INT3對(duì)應(yīng)于 64個(gè)外部 GPIO中斷。但龍芯1B的實(shí)現(xiàn)過(guò)程中,并非所有的中斷源都被使用,部分中斷源是保留未使用,
具體中斷源如下表所示:?
從上圖可以看出:
(1)GPIO31、GPIO62、GPIO63都未使用,屬于保留位,因此一個(gè)64-3=61個(gè)GPIO中斷源。
(2)并非所有的INT0和INT1的外設(shè)中斷都被使用上,實(shí)際上,龍芯1B SOC芯片,并沒(méi)有那么多外設(shè),因此,大量的位都是閑置的,屬于保留為,未定義其行為。
3.2 如何配置外部中斷源
3.3 外部中斷的中斷向量表
3.2.1 軟件中斷向量表結(jié)構(gòu)定義:ls1b_irq.c
/* 中斷向量表 */
typedef struct isr_tbl
{void (*handler)(int, void *); // 中斷句柄unsigned int arg; // 參數(shù)
} isr_tbl_t;
3.2.2 軟件中斷向量表定義:ls1b_irq.c和ls1b_irq.h
定義龍芯1B實(shí)際支持的中斷源(去除保留位)
/******************************************************************************
?* Interrupt Vector Numbers
?* MIPS_INTERRUPT_BASE should be 32 (0x20)
?******************************************************************************/
/*
?* CP0 Cause ($12) ?IP bit(15:8)=IP[7:0],
*? ? ? ?IP[1:0] is soft-interrupt
?* ? ? Status($13) ?IM bit(15:8) if mask interrupts
?*
?*/
#define LS1B_IRQ_SW0 ? ? ? ? ? ?(MIPS_INTERRUPT_BASE + 0)? ?# 協(xié)處理器的軟中斷
#define LS1B_IRQ_SW1 ? ? ? ? ? ?(MIPS_INTERRUPT_BASE + 1)? ?# 協(xié)處理器的軟中斷
#define LS1B_IRQ0_REQ ? ? ? ? ? (MIPS_INTERRUPT_BASE + 2)? #?協(xié)處理器的中斷請(qǐng)求0
#define LS1B_IRQ1_REQ ? ? ? ? ? (MIPS_INTERRUPT_BASE + 3)?? #?協(xié)處理器的中斷請(qǐng)求1
#define LS1B_IRQ2_REQ ? ? ? ? ? (MIPS_INTERRUPT_BASE + 4)?? #?協(xié)處理器的中斷請(qǐng)求2
#define LS1B_IRQ3_REQ ? ? ? ? ? (MIPS_INTERRUPT_BASE + 5)?? #?協(xié)處理器的中斷請(qǐng)求3
#define LS1B_IRQ_PERF ? ? ? ? ? (MIPS_INTERRUPT_BASE + 6)? ?# 協(xié)處理器的性能統(tǒng)計(jì)中斷
#define LS1B_IRQ_CNT ? ? ? ? ? ?(MIPS_INTERRUPT_BASE + 7)? ? # 協(xié)處理器的計(jì)數(shù)或tick中斷,操作系統(tǒng)調(diào)度使用
/*
?* Interrupt Control 0 Interrupts: 中斷控制器0支持的外設(shè)中斷數(shù)量:29個(gè)
?*/
#define LS1B_IRQ0_BASE ? ? ? ? ?(MIPS_INTERRUPT_BASE + 8)
#define LS1B_UART0_IRQ ? ? ? ? ?(LS1B_IRQ0_BASE + 2)
#define LS1B_UART1_IRQ ? ? ? ? ?(LS1B_IRQ0_BASE + 3)
#define LS1B_UART2_IRQ ? ? ? ? ?(LS1B_IRQ0_BASE + 4)
#define LS1B_UART3_IRQ ? ? ? ? ?(LS1B_IRQ0_BASE + 5)
#define LS1B_CAN0_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 6)
#define LS1B_CAN1_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 7)
#define LS1B_SPI0_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 8)
#define LS1B_SPI1_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 9)
#define LS1B_AC97_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 10)
#define LS1B_DMA0_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 13)
#define LS1B_DMA1_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 14)
#define LS1B_DMA2_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 15)
#define LS1B_PWM0_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 17)
#define LS1B_PWM1_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 18)
#define LS1B_PWM2_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 19)
#define LS1B_PWM3_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 20)
#define LS1B_RTC0_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 21)
#define LS1B_RTC1_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 22)
#define LS1B_RTC2_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 23)
#define LS1B_TOY0_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 24)
#define LS1B_TOY1_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 25)
#define LS1B_TOY2_IRQ ? ? ? ? ? (LS1B_IRQ0_BASE + 26)
#define LS1B_RTC_IRQ ? ? ? ? ? ?(LS1B_IRQ0_BASE + 27)
#define LS1B_TOY_IRQ ? ? ? ? ? ?(LS1B_IRQ0_BASE + 28)
#define LS1B_UART4_IRQ ? ? ? ? ?(LS1B_IRQ0_BASE + 29)
#define LS1B_UART5_IRQ ? ? ? ? ?(LS1B_IRQ0_BASE + 30)
/*
?* Interrupt Control 1 interrupts:中斷控制器1支持的外設(shè)中斷:4個(gè)
?*/
#define LS1B_IRQ1_BASE ? ? ? ? ?(MIPS_INTERRUPT_BASE + 40)
#define LS1B_EHCI_IRQ ? ? ? ? ? (LS1B_IRQ1_BASE + 0)
#define LS1B_OHCI_IRQ ? ? ? ? ? (LS1B_IRQ1_BASE + 1)
#define LS1B_GMAC0_IRQ ? ? ? ? ?(LS1B_IRQ1_BASE + 2)
#define LS1B_GMAC1_IRQ ? ? ? ? ?(LS1B_IRQ1_BASE + 3)
/*
?* Interrupt Control 2 interrupts (GPIO):中斷控制器2支持的GPIO中斷數(shù):31個(gè)
?*/
#define LS1B_IRQ2_BASE ? ? ? ? ?(MIPS_INTERRUPT_BASE + 72)
#define LS1B_GPIO0_IRQ ? ? ? ? ?(LS1B_IRQ2_BASE + 0)
#define LS1B_GPIO1_IRQ ? ? ? ? ?(LS1B_IRQ2_BASE + 1)
#define LS1B_GPIO2_IRQ ? ? ? ? ?(LS1B_IRQ2_BASE + 2)
#define LS1B_GPIO3_IRQ ? ? ? ? ?(LS1B_IRQ2_BASE + 3)
#define LS1B_GPIO4_IRQ ? ? ? ? ?(LS1B_IRQ2_BASE + 4)
#define LS1B_GPIO5_IRQ ? ? ? ? ?(LS1B_IRQ2_BASE + 5)
#define LS1B_GPIO6_IRQ ? ? ? ? ?(LS1B_IRQ2_BASE + 6)
#define LS1B_GPIO7_IRQ ? ? ? ? ?(LS1B_IRQ2_BASE + 7)
#define LS1B_GPIO8_IRQ ? ? ? ? ?(LS1B_IRQ2_BASE + 8)
#define LS1B_GPIO9_IRQ ? ? ? ? ?(LS1B_IRQ2_BASE + 9)
#define LS1B_GPIO10_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 10)
#define LS1B_GPIO11_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 11)
#define LS1B_GPIO12_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 12)
#define LS1B_GPIO13_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 13)
#define LS1B_GPIO14_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 14)
#define LS1B_GPIO15_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 15)
#define LS1B_GPIO16_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 16)
#define LS1B_GPIO17_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 17)
#define LS1B_GPIO18_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 18)
#define LS1B_GPIO19_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 19)
#define LS1B_GPIO20_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 20)
#define LS1B_GPIO21_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 21)
#define LS1B_GPIO22_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 22)
#define LS1B_GPIO23_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 23)
#define LS1B_GPIO24_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 24)
#define LS1B_GPIO25_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 25)
#define LS1B_GPIO26_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 26)
#define LS1B_GPIO27_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 27)
#define LS1B_GPIO28_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 28)
#define LS1B_GPIO29_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 29)
#define LS1B_GPIO30_IRQ ? ? ? ? (LS1B_IRQ2_BASE + 30)
?
/*
?* Interrupt Control 3 source bit (GPIO):中斷控制器3支持的GPIO中斷數(shù):30個(gè)。
?*/
#define LS1B_IRQ3_BASE ? ? ? ? ?(MIPS_INTERRUPT_BASE + 104)
#define LS1B_GPIO32_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 0)
#define LS1B_GPIO33_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 1)
#define LS1B_GPIO34_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 2)
#define LS1B_GPIO35_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 3)
#define LS1B_GPIO36_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 4)
#define LS1B_GPIO37_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 5)
#define LS1B_GPIO38_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 6)
#define LS1B_GPIO39_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 7)
#define LS1B_GPIO40_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 8)
#define LS1B_GPIO41_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 9)
#define LS1B_GPIO42_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 10)
#define LS1B_GPIO43_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 11)
#define LS1B_GPIO44_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 12)
#define LS1B_GPIO45_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 13)
#define LS1B_GPIO46_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 14)
#define LS1B_GPIO47_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 15)
#define LS1B_GPIO48_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 16)
#define LS1B_GPIO49_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 17)
#define LS1B_GPIO50_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 18)
#define LS1B_GPIO51_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 19)
#define LS1B_GPIO52_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 20)
#define LS1B_GPIO53_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 21)
#define LS1B_GPIO54_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 22)
#define LS1B_GPIO55_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 23)
#define LS1B_GPIO56_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 24)
#define LS1B_GPIO57_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 25)
#define LS1B_GPIO58_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 26)
#define LS1B_GPIO59_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 27)
#define LS1B_GPIO60_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 28)
#define LS1B_GPIO61_IRQ ? ? ? ? (LS1B_IRQ3_BASE + 29)
#define LS1B_MAXIMUM_VECTORS ? ? ? ?(LS1B_GPIO61_IRQ+1)
#define BSP_INTERRUPT_VECTOR_MIN ? ?0
#define BSP_INTERRUPT_VECTOR_MAX ? ?LS1B_MAXIMUM_VECTORS
備注:中斷向量表中一共支持8 + 29 + 4 + 31 + 30 = 8 + 33 + 61 = 102個(gè)中斷。
中斷向量表:
static isr_tbl_t isr_table[BSP_INTERRUPT_VECTOR_MAX];
3.3.3 默認(rèn)的中斷處理或中斷服務(wù)程序:ls1b_irq.c
/** 默認(rèn)中斷 */
static void mips_default_isr(int vector, void *arg)
{unsigned int sr;unsigned int cause;mips_get_sr(sr);mips_get_cause(cause);printf("Unhandled isr exception: vector 0x%02x, cause 0x%08X, sr 0x%08X\n",vector, cause, sr);while (1);
}
3.3.4 中斷向量表的初始化
/* * 初始化*/
void mips_init_isr_table(void)
{unsigned int i;for (i=0; i<BSP_INTERRUPT_VECTOR_MAX; i++) {isr_table[i].handler = mips_default_isr;isr_table[i].arg = i;}
}
使用默認(rèn)的中斷服務(wù)程序mips_default_isr初始化中斷向量表。
3.3.5 安裝用戶自定義的中斷服務(wù)程序的安裝與移除
void ls1x_install_irq_handler(int vector, void (*isr)(int, void *), void *arg)
{if ((vector >= 0) && (vector < BSP_INTERRUPT_VECTOR_MAX)){mips_interrupt_disable();isr_table[vector].handler = isr;isr_table[vector].arg = (unsigned int)arg;mips_interrupt_enable();}
}void ls1x_remove_irq_handler(int vector)
{if ((vector >= 0) && (vector < BSP_INTERRUPT_VECTOR_MAX)){mips_interrupt_disable();isr_table[vector].handler = mips_default_isr;isr_table[vector].arg = vector;mips_interrupt_enable();}
}