使用Boost库中的high_bit_mask_t和low_bits_mask_t:一个测试程序

479 篇文章 ¥59.90 ¥99.00
本文介绍了如何使用Boost库中的high_bit_mask_t和low_bits_mask_t进行位操作,通过示例代码展示它们的功能,用于生成指定数量高位或低位为1的掩码。

使用Boost库中的high_bit_mask_t和low_bits_mask_t:一个测试程序

Boost是一个受欢迎的C++库,提供了许多有用的功能和组件,可以帮助开发人员更轻松地编写高效和可靠的代码。其中之一是高位掩码(high_bit_mask_t)和低位掩码(low_bits_mask_t)类型,它们提供了一种方便的方法来操作二进制数据的高位和低位。

在本文中,我们将探讨使用Boost库中的high_bit_mask_t和low_bits_mask_t的用法,并提供一个简单的测试程序来演示它们的功能。

首先,让我们了解一下high_bit_mask_t和low_bits_mask_t的定义和用法。

high_bit_mask_t是一个无符号整数类型,用于生成指定数量最高位设置为1的掩码。它可以通过在泛型函数boost::high_bit_mask()中传递位数作为参数来创建。下面是一个示例代码片段,展示了如何使用high_bit_mask_t:

#include <boost/integer.hpp>

int main
#include <arch.h> #include <arch_helpers.h> #include <platform_def.h> #include <interrupt_mgmt.h> #include <platform.h> #include <bl_common.h> #include <debug.h> #include <mmio.h> #include <runtime_svc.h> #include <hwtf_plat_gic.h> #include <hwtf_misc_lib.h> #include <gicv3_private.h> #include <tf_log.h> uint32_t gic_interrupt_type_to_line(uint32_t cpuif_base, uint32_t type) { uint32_t gicc_ctlr_val = (uint32_t)mmio_read_32(cpuif_base + GICC_CTLR); if ((type == INTR_TYPE_NS) || ((gicc_ctlr_val & FIQ_EN) == 0)) { return __builtin_ctz(SCR_IRQ_BIT); } else { return __builtin_ctz(SCR_FIQ_BIT); } } /* gicr_waker_processorsleep 0->1:表示CPU准备进入休眠状态,请GIC准备休眠; */ void plat_ic_waker_down_cpu(unsigned long gicr_base, unsigned int coreid) { mmio_write_32((uintptr_t)gicr_base + GICR_WAKER + ((uintptr_t)coreid << 18), 0x2); // 18:bit移位 0x2 bit1从 0 -> 1 } /* ****************************************************************************** * t00216239: Wait Gic Waker Down. * **************************************************************************** */ void plat_ic_check_waker_down_cpu(unsigned long gicr_base, unsigned int coreid) { uint32_t time_count = 0; while ((mmio_read_32((uintptr_t)gicr_base + GICR_WAKER + ((uintptr_t)coreid << 18)) & 0x4) != 0x4) { // 18:bit移位 0x4获取bit2的值 MicroSecondDelay(100); // 延时100us time_count++; if (time_count > 5000) { // 5000:这里最大等待500ms退出,保证充足的裕量,且不会触发饿狗 break; } } } /* BEGIN: Modefied by y00300051, 2016/05/18 问题单号:DTS2016051707015 * 产品约束正常情况函数不能有任何打印,错误打印只能向stderr打印,不能向stdout打印 */ uint32_t gic_gicd_disable_spi(uint32_t gicd_base, uint32_t spi_id) { uint32_t iceanbler = 0; uint32_t reg_index; uint32_t bit_index; if (!VERIFY_SPI_ID(spi_id)) { aft_print(LOG_LEVEL_ERROR, " The input Shared Peripheral Interrupts ID(%d) is out of range(%d - %d)!\r\n", spi_id, MIN_EXTERNEL_INT_ID, MAX_EXTERNEL_INT_ID); return (uint32_t)FAILED; } reg_index = (spi_id >> 5) - 1; // 5:bit移位 bit_index = spi_id & MAX_PPI_ID; SETBIT(iceanbler, bit_index); mmio_write_32(gicd_base + GICD_ICENABLER_SPI + (uint32_t)(reg_index << 2), iceanbler); // 2:bit移位 aft_print(LOG_LEVEL_INFO, "spi_id:%u, iceanbler:0x%x\n", spi_id, iceanbler); isb(); dsb(); return OK; } uint32_t gic_gicd_get_spi_enable_status(uint32_t gicd_base, uint32_t spi_id, uint32_t *p_enable) { uint32_t iseanbler; uint32_t reg_index; uint32_t bit_index; if (!VERIFY_SPI_ID(spi_id)) { aft_print(LOG_LEVEL_ERROR, " The input Shared Peripheral Interrupts ID(%d) is out of range(%d - %d)!\r\n", spi_id, MIN_EXTERNEL_INT_ID, MAX_EXTERNEL_INT_ID); return (uint32_t)FAILED; } reg_index = (spi_id >> 5) - 1; // 5:bit移位 bit_index = spi_id & MAX_PPI_ID; // 这个寄存器是cpu banked ,所有cpu用同样的地址 iseanbler = (uint32_t)mmio_read_32(gicd_base + GICD_ISENALER_SPI + (uint32_t)(reg_index << 2)); // 2:bit移位 *p_enable = TSTBIT(iseanbler, bit_index); return OK; } uint32_t gic_gicd_get_spi_active(uint32_t gicd_base, uint32_t spi_id, uint32_t *p_status) { uint32_t gicd_isactiver; uint32_t reg_index; uint32_t bit_index; #if defined CPU_HI1383 if (!VERIFY_SPI_ID(spi_id)) { aft_print(LOG_LEVEL_ERROR, "The input Shared Peripheral Interrupts ID(%d) is out of range(%d - %d)!\r\n", spi_id, MIN_EXTERNEL_INT_ID, MAX_EXTERNEL_INT_ID); return (uint32_t)FAILED; } #endif reg_index = (spi_id >> 5) - 1; // 5:bit移位 bit_index = spi_id & MAX_PPI_ID; gicd_isactiver = (uint32_t)mmio_read_32(gicd_base + GICD_ISACTIVER_SPI + (uint32_t)(reg_index << 2)); // 2:bit移位 *p_status = TSTBIT(gicd_isactiver, bit_index); return OK; } uint32_t gic_gicd_set_spi_igroup(uint32_t gicd_base, uint32_t spi_id, uint32_t group_id) { uint32_t reg_index; uint32_t bit_index; uint32_t igroupr; uint32_t igrpmodr; if (!VERIFY_SPI_ID(spi_id)) { aft_print(LOG_LEVEL_ERROR, "The input Shared Peripheral Interrupts ID(%d) is out of range(%d - %d)!\r\n", spi_id, MIN_EXTERNEL_INT_ID, MAX_EXTERNEL_INT_ID); return (uint32_t)FAILED; } if (group_id >= INT_GROUP_MAX) { aft_print(LOG_LEVEL_ERROR, "The input Group ID(%d) is out of range(%d)!\r\n", group_id, INT_GROUP_MAX); return (uint32_t)FAILED; } reg_index = (spi_id >> 5) - 1; // 5:bit移位 bit_index = spi_id & MAX_PPI_ID; /* Configure the GICD_IGROUPR */ igroupr = (uint32_t)mmio_read_32(gicd_base + GICD_IGROUPR_SPI + (uint32_t)(reg_index << 2)); // 2:bit移位 if ((group_id == INT_GROUP_G0S) || (group_id == INT_GROUP_G1S)) { CLRBIT(igroupr, bit_index); } else { SETBIT(igroupr, bit_index); } mmio_write_32(gicd_base + GICD_IGROUPR_SPI + (uint32_t)(reg_index << 2), igroupr); // 2:bit移位 aft_print(LOG_LEVEL_INFO, " regaddr:0x%lx w:0x%x,r:0x%x\n", (gicd_base + GICD_IGROUPR_SPI + (uint32_t)(reg_index << 2)), igroupr, // 2:bit移位 mmio_read_32(gicd_base + GICD_IGROUPR_SPI + (uint32_t)(reg_index << 2))); // 2:bit移位 /* Configure the GICD_IGRPMOD */ igrpmodr = (uint32_t)mmio_read_32(gicd_base + GICD_IGRPMODR_SPI + (uint32_t)(reg_index << 2)); // 2:bit移位 if ((group_id == INT_GROUP_G0S) || (group_id == INT_GROUP_G1NS)) { CLRBIT(igrpmodr, bit_index); } else { SETBIT(igrpmodr, bit_index); } mmio_write_32(gicd_base + GICD_IGRPMODR_SPI + (uint32_t)(reg_index << 2), igrpmodr); // 2:bit移位 aft_print(LOG_LEVEL_INFO, " igrpmodaddr:0x%lx w:0x%x,r:0x%x\n", (gicd_base + GICD_IGRPMODR_SPI + (uint32_t)(reg_index << 2)), igrpmodr, // 2:bit移位 mmio_read_32(gicd_base + GICD_IGRPMODR_SPI + (uint32_t)(reg_index << 2))); // 2:bit移位 return OK; } /* **************************************************************************** * 1. When ARE is zero, the safe state of the interrupt of this register is consistent with the definition of GICv2. * 2. When ARE is used for interrupt security status, GICR_ICFGR0 and GICR_ICFGR1 provide interrupts to RES0 and equivalent functions in GICD_ICFGR0 and GICD_ICFGR1. * 3. SGI intterupt is the default edge trigger GICD_ICFGR_SPI_NN 该寄存器每2bit表示一个N-N SPI中断是电平敏感还是边沿触发,i{0,1} GICD_ICFGR_SPI第0~1bit相应的中断号为ID32,第2~3bit相应的中断号为ID33,逐次类推。 2bit一个中断的配置域(int_cfg),其中的int_cfg[0]是保留的, int_cfg[1]:0:相应的中断为电平敏感,1:相应的中断为边沿触发 **************************************************************************** */ uint32_t gic_gicd_set_spi_icfg(uint32_t gicd_base, uint32_t spi_id, uint32_t cft_type) { uint32_t gicd_icfg; uint32_t reg_offset; uint32_t bit_offset; if (!VERIFY_SPI_ID(spi_id)) { aft_print(LOG_LEVEL_ERROR, " The input Shared Peripheral Interrupts ID(%d) is out of range(%d - %d)!\r\n", spi_id, MIN_EXTERNEL_INT_ID, MAX_EXTERNEL_INT_ID); return (uint32_t)FAILED; } if (cft_type > INT_EDGE_TIRGGERED) { aft_print(LOG_LEVEL_ERROR, " The input triggered-type (0x%x) is out of range(0x%x)!\n" "\r\n", cft_type, INT_EDGE_TIRGGERED); return (uint32_t)FAILED; } /* Program the GICD_ICFGR 寄存器地址是用对了,寄存器名写错了 */ // reg_offset代表的是第几个GICD_ICFGR_SPI,57号确实是1 故先减去0x20即前32个中断 // 4:根据代码逻辑来看是因为一个32bit的寄存器中只能存放16个spi中断的触发方式,所以要右移4bit reg_offset = (spi_id - 0x20) >> 4; // 先减去0x20即前32个中断, 然后要右移4bit bit_offset = (((spi_id & 0xF) << 1) + 1); // 0xF 取bit[3:0]的值 57号应该是19 gicd_icfg = (uint32_t)mmio_read_32(gicd_base + GICD_ICFGR_SPI_NN + (uint32_t)(reg_offset << 2)); // 2:bit移位 gicd_icfg &= ~((uint32_t)0x01 << bit_offset); gicd_icfg |= (cft_type << bit_offset); mmio_write_32(gicd_base + GICD_ICFGR_SPI_NN + (uint32_t)(reg_offset << 2), gicd_icfg); // 2:bit移位 aft_print(LOG_LEVEL_INFO, "spiid:%d, regaddr:0x%lx, bit_offset:%d, write GICD_ICFGR_SPI:0x%x, read=0x%x\n", spi_id, (gicd_base + GICD_ICFGR_SPI_NN + (uint32_t)(reg_offset << 2)), bit_offset, gicd_icfg, // 2:bit移位 mmio_read_32(gicd_base + GICD_ICFGR_SPI_NN + (uint32_t)(reg_offset << 2))); // 2:bit移位 return OK; } /* **************************************************************************** 1. For SGI and PPI interrupts, the byte in this interrupted GICD_IPRIORITYR0 to GICD_IPRIORITYR7 is RES0, which provides equivalent functionality from the bytes in GICR_IPRIORITYR0 to GICR_IPRIORITYR7 GICD_IPRIORITYRn第0~7bit相应的中断号为ID4n,第8~15bit相应的中断号为ID4n+1,逐次类推。值越大优先级越低。 注:(1)此寄存器是按字节访问的; (2)只能安全访问才能正确访问Group0中断优先级; (3)安全中断对应的priority域的高5bit有效,非安全中断对应的priority域的高4bit有效。 **************************************************************************** */ uint32_t gic_gicd_set_spi_ipriority_s(uint32_t gicd_base, uint32_t spi_id, uint32_t prior) { uint32_t gicd_ipriority; uint32_t reg_offset; uint32_t bit_offset; uint32_t active_status = 0; uint32_t enable_status = 0; if (!VERIFY_SPI_ID(spi_id)) { aft_print(LOG_LEVEL_ERROR, "SPI ID The input Shared Peripheral Interrupts ID(%d) is out of range(%d - %d)!\r\n", spi_id, MIN_EXTERNEL_INT_ID, MAX_EXTERNEL_INT_ID); return (uint32_t)FAILED; } if (prior > MAX_S_PRIORITY) { aft_print(LOG_LEVEL_ERROR, "The input priority(%d) is out of range(%d)!" "\r\n", prior, MAX_S_PRIORITY); return OK; } /* Ensure the interrupt is not active */ (void)gic_gicd_get_spi_active(gicd_base, spi_id, &active_status); if (active_status != 0) { aft_print(LOG_LEVEL_INFO, "get spi active Shared Peripheral Interrupts %d is active!\r\n", spi_id); } /* Ensure that the interrupt is disabled */ (void)gic_gicd_get_spi_enable_status(gicd_base, spi_id, &enable_status); if (enable_status != 0) { (void)gic_gicd_disable_spi(gicd_base, spi_id); } /* Program the priority */ // 减去0x20即前32个中断 // 根据代码逻辑来看是因为一个32bit的寄存器中只能存放四个中断的优先级,所以要右移2bit,reg_offset代表的是第几个GICD_IPRIORITYR reg_offset = (spi_id - 0x20) >> 2; // 减去0x20即前32个中断, 然后右移2bit // 一个中断占据8bit,所以要<<3,另外安全中断对应的priority域的高5bit有效,所以要加上3 bit_offset = ((spi_id & 0x3) << 3) + 0x3; // & 0x3是为了得知该spi中断在GICD_IPRIORITYR中的第几个中断 gicd_ipriority = (uint32_t)mmio_read_32(gicd_base + GICD_IPRIORITYR_SPI_S + (uint32_t)(reg_offset << 2)); // 2:bit移位 gicd_ipriority &= ~((uint32_t)0x1F << bit_offset); // 将0x1F 位移上述算出的bitoffset gicd_ipriority |= (prior << bit_offset); mmio_write_32(gicd_base + GICD_IPRIORITYR_SPI_S + (uint32_t)(reg_offset << 2), gicd_ipriority); // 2:bit移位 aft_print(LOG_LEVEL_INFO, "gicd ipriority:regaddr:0x%lx write spi_id:%u,w:0x%x,r:0x%x\n", (gicd_base + GICD_IPRIORITYR_SPI_S + (uint32_t)(reg_offset << 2)), spi_id, gicd_ipriority, // 2:bit移位 mmio_read_32(gicd_base + GICD_IPRIORITYR_SPI_S + (uint32_t)(reg_offset << 2))); // 2:bit移位 return OK; } /* GICD_ITARGETSR_SPI SPI_BLOCK每32bit对应一个中断的所有相应的CPU Interface。h{0,223} 0x0880+h*4 该寄存器为NNSPI中断分发目的CPU配置寄存器,每个中断使用一个寄存器配置,支持32个NNSPI配置。 GICD_ITARGETSRn采用位掩码的方式,设置为1说明发送到相应的核,每个中断号支持设置32个目标核。 注:只能安全访问才能正确访问Group0中断; 0x0880~0x08FC的偏移地址为NNSPI路由配置地址; 0x0900~0x0C00的偏移地址无效; */ uint32_t gic_gicd_itarget_spi2allcore(uint32_t gicd_base, uint32_t spi_id) { uint32_t itarget = 0xff; /* target to all cpu */ mmio_write_32((uintptr_t)(gicd_base + GICD_ITARGETSR_LOW + (uintptr_t)spi_id * 4), // 4 itarget); // 从GICD_ITARGETSR_LOW开始,不用对spiid减31了 aft_print(LOG_LEVEL_INFO, "gicd base spi_id:%u addr:0x%lx, val:0x%x\n", spi_id, gicd_base + GICD_ITARGETSR_LOW + spi_id * 4, // 4 mmio_read_32(gicd_base + GICD_ITARGETSR_LOW + (uintptr_t)spi_id * 4)); // 4 return OK; } /* **************************************************************************** Bits corresponding to group 0 and group 1 security interrupts can only be enabled via secure access GICD_ISENABLER_SPI spi单个中断的使能寄存器,决定是否发给Cpu Interface。 m的值由GICD_TYPER.ITLinesNumber决定,m{0,2} tab 0x0104+m*4 32 RW 0x00000000 gicd_spi_setenable 31:0 RW 0x00000000 "GICD_ISENABLERn第abit相应的中断号为ID(32*n+a),第a+1bit相应的中断号为ID(32*n+a+1),逐次类推。 对于读:0:相应的中断不使能; 1:相应的中断使能 对于写:0:忽略,不起作用; 1:使能相应的中断 注:(1)只能安全访问才能访问Group0中断对应的bit;" 中断丢失 Y **************************************************************************** */ uint32_t gic_gicd_enable_spi(uint32_t gicd_base, uint32_t spi_id) { uint32_t iseanbler = 0; uint32_t reg_index; uint32_t bit_index; if (!VERIFY_SPI_ID(spi_id)) { aft_print(LOG_LEVEL_ERROR, "The input Shared Peripheral Interrupts ID(%d) is out of range(%d - %d)!\r\n", spi_id, MIN_EXTERNEL_INT_ID, MAX_EXTERNEL_INT_ID); return (uint32_t)FAILED; } reg_index = (spi_id >> 5) - 1; // 57号中断是0 bit_index = spi_id & MAX_PPI_ID; SETBIT(iseanbler, bit_index); mmio_write_32(gicd_base + GICD_ISENALER_SPI + (uint32_t)(reg_index << 2), iseanbler); // 2:bit移位 aft_print(LOG_LEVEL_INFO, " spi_id:%d reg_addr:0x%lx,bit_index:%d, w :0x%x, r:0x%x\n", spi_id, (gicd_base + GICD_ISENALER_SPI + (uint32_t)(reg_index << 2)), bit_index, iseanbler, // 2:bit移位 mmio_read_32(gicd_base + GICD_ISENALER_SPI + (uint32_t)(reg_index << 2))); // 2:bit移位 return OK; } uint32_t gic_gicd_enable_g0s(uint32_t gicd_base) { uint32_t gicd_ctlr_s; gicd_ctlr_s = (uint32_t)mmio_read_32(gicd_base + GICD_CTLR_S); gicd_ctlr_s |= gicd_ctlr_enablegrp0; mmio_write_32(gicd_base + GICD_CTLR_S, gicd_ctlr_s); aft_print(LOG_LEVEL_INFO, "gicd_ctlr_s:0x%x\n", mmio_read_32(gicd_base + GICD_CTLR_S)); isb(); dsb(); return OK; } uint32_t gic_set_mask_priority(uint32_t mask_prior) { uint32_t gicc_pmr; if (mask_prior > GIC_MAX_MASK_PRIOR) { /* Out of range mask priority */ aft_print(LOG_LEVEL_NOTICE, " mask_prior:[%u] is out of rang.\n", mask_prior); return (uint32_t)FAILED; } /* set priority of int */ // 配置GICC_PMR设置中断屏蔽优先级 gicc_pmr = (uint32_t)read_icc_pmr_el1(); gicc_pmr |= (mask_prior & 0xf8); // 0xf8:中断优先级配置值,配置bit[7]~bit[3] write_icc_pmr_el1(gicc_pmr); WARN(" write gicc_pmr:0x%x\n", gicc_pmr); return OK; } uint32_t gic_gicr_clr_waker(uint32_t gicr_base) { uint32_t gicr_waker; uint32_t i = 0; gicr_waker = mmio_read_32(gicr_base + GICR_WAKER + (((uintptr_t)(plat_my_core_pos())) << 18)); // 18:bit移位 gicr_waker &= (uint32_t)~WAKER_PS; gicr_write_waker(gicr_base + (((uintptr_t)(plat_my_core_pos())) << 18), gicr_waker); // 18:bit移位 /* Need to clear to fall of childrenasleep. */ isb(); dsb(); gicr_waker = (uint32_t)gicr_read_waker(gicr_base + (((uintptr_t)(plat_my_core_pos())) << 18)); // 18:bit移位 while ((gicr_waker & WAKER_CA) != 0) { if (i % 400 == 0) { // 每400ms喂狗一次 do_clear_watchdog(); } do_clear_watchdog(); delay_ns(1000000); // delay 1000000 ns gicr_waker = (uint32_t)gicr_read_waker(gicr_base + (((uintptr_t)(plat_my_core_pos())) << 18)); // 18:bit移位 i++; if (i > 10000) { // 超过10000*1000000ns aft_print(LOG_LEVEL_INFO, "reset_core gicr not waker!\n"); break; } } return OK; } uint32_t gicv3_interrupt_type_to_line(uint32_t type) { if (type != INTR_TYPE_NS && type != INTR_TYPE_EL3 && type != INTR_TYPE_S_EL1) { return (uint32_t)FAILED; } return __builtin_ctz(SCR_FIQ_BIT); } /* **************************************************************************** Set a Shared Peripheral Interrupts route to the processor specified by a.b.c.d [NOTE]: 1. These registers provide the routing information when ARE is set for the security state of the associated interrupts. When ARE is not set, these registers are RES0. 2. In systems supporting two security states, the GICD_IROUTERn registers associated with secure interrupts may only be accessed by secure accesses and are RAZ/WI for non-secure accesses 3. when ARE becomes one for a security state the value of all writeable fields in this register is UNKNOWN for that security state. GICD_IROUTERN_L 亲性路由寄存器 GICD_IROUTERn_l每个寄存器对应一个中断ID,寄存器n对应IDn。 0:按亲性路由配置的a.b.c.d CPU进行路由; 1:路由给整个系统所有CPU中的一个。 注 (1)中断ID0~31对应SGIPPI中断,SGI的路由方式由SGIR或generateSGI命令获取, PPI中断只发给本处理器,均不适用route寄存器。所以本寄存器对0~31中断保留。 (2)只能安全访问才能访问Group0中断对应的bit; gicd_affinity2 23:16 RW 0x00 "亲性分层中,A2的值。 bit[6:5]指示Socket ID,范围0~3; bit[4:3]指示Socket内SCLID,范围0~3。 bit[2:0]指示SCL内CLUID,范围0~7。其他bit无效为RO/WI;" gicd_affinity1 15:8 RW 0x00 "bit[1:0]指示CLUSTER内CPUID,范围0~3。其他bit无效为RO/WI;" gicd_affinity0 7:0 RO 0x00 Affinity level 0. The level identifies individual threads within a multi-threaded core. The taishan core is single-threaded, so this field has the value 0x00. **************************************************************************** */ uint32_t gic_gicd_route_spi2cpu(uint32_t gicd_base, uint32_t spi_id, uint32_t aff2, uint32_t aff1, uint32_t aff0) { uint32_t gicd_irouter; uint32_t active_status = 0; uint32_t enable_status = 0; uint32_t Die_id = 0x18; /* Ensure the interrupt is not active */ (void)gic_gicd_get_spi_active(gicd_base, spi_id, &active_status); if (active_status != 0) { aft_print(LOG_LEVEL_INFO, "get spi active SPI_id:%d is active!\r\n", spi_id); } /* Ensure that the interrupt is disabled */ (void)gic_gicd_get_spi_enable_status(gicd_base, spi_id, &enable_status); if (enable_status != 0) { (void)gic_gicd_disable_spi(gicd_base, spi_id); } gicd_irouter = aff0 | (aff1 << 8) | ((Die_id | aff2) << 16); // 8,16:bit移位 mmio_write_32(gicd_base + GICD_IROUTERN_L + (spi_id << 3), gicd_irouter); // 3:bit移位 aft_print(LOG_LEVEL_INFO, "get spi active regaddr:0x%lx,w:0x%x, r:0x%x\n", gicd_base + GICD_IROUTERN_L + (spi_id << 3), gicd_irouter, // 3:bit移位 mmio_read_32(gicd_base + GICD_IROUTERN_L + (spi_id << 3))); // 3:bit移位 return OK; } /* BEGIN: Modefied by y00300051, 2016/3/12 问题单号:DTS2016031202055 */ uint32_t gic_gicd_disable_g0s(uint32_t gicd_base) { uint32_t gicd_ctlr_s; gicd_ctlr_s = (uint32_t)mmio_read_32(gicd_base + GICD_CTLR_S); gicd_ctlr_s &= (~gicd_ctlr_enablegrp0); mmio_write_32(gicd_base + GICD_CTLR_S, gicd_ctlr_s); aft_print(LOG_LEVEL_INFO, "write gicd_ctlr_sa:0x%x\n", gicd_ctlr_s); isb(); dsb(); return OK; } uint32_t gic_gicd_disable_g1s(uint32_t gicd_base) { uint32_t gicd_ctlr_s; gicd_ctlr_s = (uint32_t)mmio_read_32(gicd_base + GICD_CTLR_S); gicd_ctlr_s &= (~gicd_ctlr_enablesgrp1); mmio_write_32(gicd_base + GICD_CTLR_S, gicd_ctlr_s); aft_print(LOG_LEVEL_INFO, "gicd_ctlr_ss:0x%x\n", gicd_ctlr_s); isb(); dsb(); return OK; } uint32_t gic_gicd_disable_g1ns(uint32_t gicd_base) { uint32_t gicd_ctlr_s; gicd_ctlr_s = (uint32_t)mmio_read_32(gicd_base + GICD_CTLR_NS); gicd_ctlr_s &= (~gicd_ctlr_enablensgrp1); mmio_write_32(gicd_base + GICD_CTLR_NS, gicd_ctlr_s); isb(); dsb(); aft_print(LOG_LEVEL_INFO, "agicd_ctlr_ns:0x%x\n", gicd_ctlr_s); return OK; } /* END: Modefied by y00300051, 2016/3/12 */ uint32_t gic_gicd_enable_g1s(uint32_t gicd_base) { uint32_t gicd_ctlr_s; gicd_ctlr_s = (uint32_t)mmio_read_32(gicd_base + GICD_CTLR_S + (uint32_t)(0 << 2)); // 2:bit移位 gicd_ctlr_s |= gicd_ctlr_enablesgrp1; mmio_write_32(gicd_base + GICD_CTLR_S + (uint32_t)(0 << 2), gicd_ctlr_s); // 2:bit移位 isb(); dsb(); aft_print(LOG_LEVEL_INFO, "ssgicd_ctlr_s:0x%x\n", gicd_ctlr_s); return OK; } /* GICD_CTLR_S Distributor的控制寄存器(安全操作) tab 0x0000 32 RW 0x00000030 gicd_ctlr_rwp 31 RO 0x0 "所有Re-Distributor、CPU对写GICD_CTLR的group使能位或者ARE,或写GICD_ICENABLERn是否可见。 0:所有后续模块对写相关寄存器已经全部可见; 1:所有后续模块对写相关寄存器还没全部可见。" reserved 30:8 RO 0x000000 保留 gicd_ctlr_e1nwf 7 RW 0x0 "Enable “1 of N” Wake-up Functionality: 0:a processor that is asleep cannot be picked for 1 of N interrupts. 1:a processor that is asleep can be picked for 1 of N interrupts;" gicd_ctlr_ds 6 RW 0x0 "安全去使能位 0:不允许非安全模式访问修改group0相关寄存器。 1:允许非安全模式访问修改group0相关寄存器;该寄存器允许从0变为1;不允许从1变为0;" gicd_ctlr_are_ns 5 RO 0x1 "非安全中断亲性路由使能控制。 0:非安全中断亲性路由不使能; 1:非安全中断亲性路由使能。 注意:硬件没有保证该bit不从会1变为0,需要软件保证该bit不从1变为0; 该寄存器同时被作为硬件遵循的规范GICV2、GICV3的版本指示, 该bit被固定位1,表示硬件只遵循GICV3规范。" gicd_ctlr_are_s 4 RO 0x1 "安全中断亲性路由使能控制。 0:安全中断亲性路由不使能; 1:安全中断亲性路由使能。 该寄存器同时被作为硬件遵循的规范GICV2、GICV3的版本指示, 该bit被固定位1,表示硬件只遵循GICV3规范。" reserved 3 RO 0x0 保留 gicd_ctlr_enablesgrp1 2 RW 0x0 "Secure Group 1中断使能控制。 0:Secure Group 1中断不使能; 1:Secure Group 1中断使能。 " gicd_ctlr_enablensgrp1 1 RW 0x0 "Non-Secure Group 1中断使能控制。 0:Non-Secure Group 1中断不使能; 1:Non-Secure Group 1中断使能。" gicd_ctlr_enablegrp0 0 RW 0x0 "Secure Group 0中断使能控制。 0:Secure Group 0中断不使能; 1:Secure Group 0中断使能。" */ uint32_t gic_gicd_enable_are(uint32_t gicd_base) { uint32_t gicd_ctlr_s; gicd_ctlr_s = (uint32_t)mmio_read_32(gicd_base + GICD_CTLR_S); /* GICv3 need this 先关中断 :中断去使能 */ if (((gicd_ctlr_s & (uint32_t)(~gicd_ctlr_enablesgrp1)) != 0 || (gicd_ctlr_s & (uint32_t)(~gicd_ctlr_enablegrp0)) != 0 || (gicd_ctlr_s & (uint32_t)(~gicd_ctlr_enablensgrp1)) != 0)) { gicd_ctlr_s &= ~(gicd_ctlr_enablesgrp1 | gicd_ctlr_enablegrp0 | gicd_ctlr_enablensgrp1); mmio_write_32(gicd_base + GICD_CTLR_S, gicd_ctlr_s); WARN("GICD_CTLR_S:Clr bit (gicd_ctlr_enablesgrp1 |" "gicd_ctlr_enablegrp0 | gicd_ctlr_enablensgrp1)\n"); } // 亲性路由使能 gicd_ctlr_s |= (gicd_ctlr_are_s | gicd_ctlr_are_ns); mmio_write_32(gicd_base + GICD_CTLR_S, gicd_ctlr_s); isb(); dsb(); aft_print(LOG_LEVEL_INFO, "dsgicd_ctlr_s:0x%x\n", mmio_read_32(GICD_BASE + GICD_CTLR_S)); return OK; } 这是中断优先级的相关代码,请结合进行分析,给出完整的结论
11-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值