目录

  • 背景介绍
  • Redistributor系统位置
  • 系统上电,CPU如何与GIC redistributor connect
    • GICR_WAKER寄存器
    • 上电流程,行为描述
  • 系统下电,CPU如何与GIC redistributor disconnect
    • 下电流程,行为描述

背景介绍

GIC电源管理,ARM官方手册,只有一页描述:
值得注意的是:

1、在符合GICv3体系结构的实现中,CPU接口和PE必须位于同一个位置power domain,但它不必与关联的Redistributor所在的power domain相同。这意味着可能出现PE及其CPU接口断电的情况,Redistributor、Distributor及其子系统都已通电。在这种情况下,GIC架构需要支持,向PE和CPU接口发送通电事件信号机制。

2、ARM强烈建议,如果该PE上的唤醒软件无法处理中断,GIC的配置方式不应使中断唤醒特定的PE。GICv3提供电源管理来控制这种情况,因为该架构的设计允许由一个组织设计的再分配器,用于由一个组织设计的PEs和CPU接口不同的组织。

3、Redistributor上电时,在关闭CPU接口和PE之前,软件必须将CPU接口和Redistributor之间的接口进入静态状态,否则系统将变为不可预期状态。

4、GIC支持通过设置GICR_WAKER,可以启动到静态状态的转换。进程睡眠到1。当CPU处于静止状态时,GICR_WAKER。ChildrenAsleep也设置为1。

那么Redistributor、GICR_WAKER在系统位置是怎么样的呢?

Redistributor系统位置

在带有gicv3的soc架构中,其框图如下所示:

gicv3中的redistributor与core中的cpu interface通过AXI-Stream进行通信。

系统上电,CPU如何与GIC redistributor connect

当core上电之后,需要将core中cpu interface与gic中的redistributor进行connect,这样将来gic才可以将中断发送给core。

connection的流程如下所示:

GICR_WAKER寄存器

上电流程,行为描述

  1. 执行在core的程序,将GICR_WAKER.ProcessorSleep位给置低,表示要connect redistributor。
  2. redistributor在完成connect之后,将GICR_WAKER.ChildrenAsleep位给置低,表示connect完成。
  3. 执行在core的程序,查询GICR_WAKER.ChildAsleep位是否为0,如果不是,表示redistributor还没有完成connect操作,就继续查询。
  4. 如果查询到0,表示connect完成,接着做之后的初始化工作。

其汇编代码如下:

/******************************************************************************* This function marks the core as awake in the re-distributor and* ensures that the interface is active.*****************************************************************************/
void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base)
{/** The WAKER_PS_BIT should be changed to 0* only when WAKER_CA_BIT is 1.*/assert((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U);/* Mark the connected core as awake *//* 执行在core的程序,将GICR_WAKER.ProcessorSleep位给置低,* 表示要connect redistributor。*/gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT);/* Wait till the WAKER_CA_BIT changes to 0 *//* 执行在core的程序,查询GICR_WAKER.ChildAsleep位是否为0,* 如果不是,表示redistributor还没有完成connect操作,就继续查询。*/while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U) {}
}/******************************************************************************** This function enables the GIC CPU interface of the calling CPU using only* system register accesses.******************************************************************************/
void gicv3_cpuif_enable(unsigned int proc_num)
{uintptr_t gicr_base;u_register_t scr_el3;unsigned int icc_sre_el3;assert(gicv3_driver_data != NULL);assert(proc_num < gicv3_driver_data->rdistif_num);assert(gicv3_driver_data->rdistif_base_addrs != NULL);assert(IS_IN_EL3());/* Mark the connected core as awake *//* 表示要connect redistributor */gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];gicv3_rdistif_mark_core_awake(gicr_base);/* Disable the legacy interrupt bypass */icc_sre_el3 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT;/** Enable system register access for EL3 and allow lower exception* levels to configure the same for themselves. If the legacy mode is* not supported, the SRE bit is RAO/WI*/icc_sre_el3 |= (ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT);write_icc_sre_el3(read_icc_sre_el3() | icc_sre_el3);scr_el3 = read_scr_el3();/** Switch to NS state to write Non secure ICC_SRE_EL1 and* ICC_SRE_EL2 registers.*/write_scr_el3(scr_el3 | SCR_NS_BIT);isb();write_icc_sre_el2(read_icc_sre_el2() | icc_sre_el3);write_icc_sre_el1(ICC_SRE_SRE_BIT);isb();/* Switch to secure state. */write_scr_el3(scr_el3 & (~SCR_NS_BIT));isb();/* Write the secure ICC_SRE_EL1 register */write_icc_sre_el1(ICC_SRE_SRE_BIT);isb();/* Program the idle priority in the PMR */write_icc_pmr_el1(GIC_PRI_MASK);/* Enable Group0 interrupts */write_icc_igrpen0_el1(IGRPEN1_EL1_ENABLE_G0_BIT);/* Enable Group1 Secure interrupts */write_icc_igrpen1_el3(read_icc_igrpen1_el3() |IGRPEN1_EL3_ENABLE_G1S_BIT);isb();
}/******************************************************************************** This function initialises the GIC Redistributor interface of the calling CPU* (identified by the 'proc_num' parameter) based upon the data provided by the* platform while initialising the driver.******************************************************************************/
void gicv3_rdistif_init(unsigned int proc_num)
{uintptr_t gicr_base;unsigned int bitmap;uint32_t ctlr;assert(gicv3_driver_data != NULL);assert(proc_num < gicv3_driver_data->rdistif_num);assert(gicv3_driver_data->rdistif_base_addrs != NULL);assert(gicv3_driver_data->gicd_base != 0U);ctlr = gicd_read_ctlr(gicv3_driver_data->gicd_base);assert((ctlr & CTLR_ARE_S_BIT) != 0U);assert(IS_IN_EL3());/* Power on redistributor */gicv3_rdistif_on(proc_num);gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];assert(gicr_base != 0U);/* Set the default attribute of all SGIs and (E)PPIs */gicv3_ppi_sgi_config_defaults(gicr_base);bitmap = gicv3_secure_ppi_sgi_config_props(gicr_base,gicv3_driver_data->interrupt_props,gicv3_driver_data->interrupt_props_num);/* Enable interrupt groups as required, if not already */if ((ctlr & bitmap) != bitmap) {gicd_set_ctlr(gicv3_driver_data->gicd_base, bitmap, RWP_TRUE);}
}/******************************************************************************* ARM common helper to initialize the GIC. Only invoked by BL31*****************************************************************************/
void __init plat_arm_gic_init(void)
{gicv3_distif_init();gicv3_rdistif_init(plat_my_core_pos());gicv3_cpuif_enable(plat_my_core_pos());
}

系统下电,CPU如何与GIC redistributor disconnect

当core下电之后,需要将core中cpu interface与gic中的redistributor进行disconnect,这样将来gic才不会将中断发送给core。

disconnection的流程如下所示:

下电流程,行为描述

  1. 执行在core的程序,先将cpu interface的中断组使能给disable。
  2. 执行在core的程序,将GICR_WAKER.ProcessorSleep位给置高,表示要disconnect redistributor。
  3. redistributor给cpu interface发送 Quiesce包。
  4. cpu interface清掉内部所有pending的中断。
  5. 清除完毕后,cpu interface回发Quiesce Acknowledge包给redistibutor。
  6. redistributor收到cpu interface回发的响应之后,将GICR_WAKER.ChildrenAsleep位给置高,表示disconnect完成。
  7. 执行在core的程序,查询GICR_WAKER.ChildAsleep位是否为1,如果不是,表示redistributor还没有完成connect操作,就继续查询。
  8. 如果查询到1,表示disconnect完成。

其汇编代码如下:

/******************************************************************************* This function marks the core as asleep in the re-distributor and ensures* that the interface is quiescent.*****************************************************************************/
void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base)
{/* Mark the connected core as asleep *//* 执行在core的程序,将GICR_WAKER.ProcessorSleep位给置高,* 表示要disconnect redistributor。*/gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_PS_BIT);/* Wait till the WAKER_CA_BIT changes to 1 *//* 执行在core的程序,查询GICR_WAKER.ChildAsleep位是否为1,* 如果不是,表示redistributor还没有完成connect操作,就继续查询。*/while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) == 0U) {}
}/******************************************************************************** This function disables the GIC CPU interface of the calling CPU using* only system register accesses.******************************************************************************/
void gicv3_cpuif_disable(unsigned int proc_num)
{uintptr_t gicr_base;assert(gicv3_driver_data != NULL);assert(proc_num < gicv3_driver_data->rdistif_num);assert(gicv3_driver_data->rdistif_base_addrs != NULL);assert(IS_IN_EL3());/* Disable legacy interrupt bypass */write_icc_sre_el3(read_icc_sre_el3() |(ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT));/* 1. 执行在core的程序,先将cpu interface的中断组使能给disable。 *//* Disable Group0 interrupts */write_icc_igrpen0_el1(read_icc_igrpen0_el1() &~IGRPEN1_EL1_ENABLE_G0_BIT);/* Disable Group1 Secure and Non-Secure interrupts */write_icc_igrpen1_el3(read_icc_igrpen1_el3() &~(IGRPEN1_EL3_ENABLE_G1NS_BIT |IGRPEN1_EL3_ENABLE_G1S_BIT));/* Synchronise accesses to group enable registers */isb();/* Mark the connected core as asleep */gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];assert(gicr_base != 0U);gicv3_rdistif_mark_core_asleep(gicr_base);
}

以下是GIC-600 支持redistributor单独下电。

static void gic600_pwr_off(uintptr_t base)
{/* Wait until group not transitioning */gicr_wait_group_not_in_transit(base);/* Power off redistributor */gicr_write_pwrr(base, PWRR_OFF);/** If this is the last man, turning this redistributor frame off will* result in the group itself being powered off and RDGPD = 1.* In that case, wait as long as it's in transition, or has aborted* the transition altogether for any reason.*/if ((gicr_read_pwrr(base) & PWRR_RDGPD) != 0U) {/* Wait until group not transitioning */gicr_wait_group_not_in_transit(base);}
}/** The Arm GIC-600 and GIC-Clayton models have their redistributors* powered down at reset.*/
/** Power off GIC-600 redistributor (if configured and detected)*/
void gicv3_rdistif_off(unsigned int proc_num)
{#if GICV3_SUPPORT_GIC600uintptr_t gicr_base = get_gicr_base(proc_num);/* Attempt to power redistributor off */if (gicv3_redists_need_power_mgmt(gicr_base)) {gic600_pwr_off(gicr_base);}
#endif
}

ARM GIC(六) GIC V3 电源/功耗管理 分析笔记。相关推荐

  1. cortex-R52 CPU的功耗管理之power gating(电源门控)

    最近在看CORTEX-R52文档时,了解了一下该处理器功耗管理相关的内容,这里记录一下power gating的部分,并加上一些自己的理解. 1.概述 power gating是一种直接关闭芯片上某一 ...

  2. SylixOS电源管理之外设功耗管理

    1.前言 在这个世界中,任何系统的运转都需要能量.如树木依靠光能生长,如马儿依靠食物奔跑,如计算机系统依靠电能运行.而能量的获取是有成本的,因此如果能在保证系统运转的基础上,尽量节省对能量的消耗,就会 ...

  3. STM8S---电源功耗管理之停机模式(halt)实现

    官方资料   可以去网络搜索中文版,或者到官方网站上去下载英文版.   英文:   译文: 主要内容简介 影响功耗的主要因素 电源系统 时钟管理 运行模式和低功耗模式 运行模式 等待模式 活跃停机模式 ...

  4. S32K144功耗管理与系统模式控制

    S32K144功耗管理与系统模式控制 1.引言 S32K144是一款NXP以Cortex M4为内核的32位汽车通用芯片,本文主要介绍该芯片的功耗管理与系统模式控制相关内容,如低功耗等运行模式.参考文 ...

  5. 第六讲:Obj-C 内存管理4 - 自动释放池

    转:http://tigercat1977.blog.163.com/blog/static/2141561122012111294616203/ 第六讲:Obj-C 内存管理4 - 自动释放池 主要 ...

  6. NET快速信息化系统开发框架 V3.2 - “用户管理”主界面使用多表头展示、增加打印功能...

    NET快速信息化系统开发框架 V3.2 -> "用户管理"主界面使用多表头展示.增加打印功能 RDIFrameowrk.NET 用户管理是使用非常频繁的模块,由于需要展示的字 ...

  7. Android7.0 PowerManagerService 之亮灭屏(二) PMS 电源状态管理updatePowerStateLocked()...

    本篇注意接着上篇[Android7.0 PowerManagerService 之亮灭屏(一)]继续分析量灭屏的流程,这篇主要分析PMS的状态计算和更新流程,也是PMS中最为重要和复杂的一部分电源状态 ...

  8. 信息系统项目管理师必背核心考点(六十)项目集管理

    科科过为您带来软考信息系统项目管理师核心重点考点(六十)项目集管理,内含思维导图+真题 [信息系统项目管理师核心考点]项目集指导委员会 1.又称项目集治理委员会,主要负责定义并执行恰当的项目集治理体系 ...

  9. 信息系统项目管理师必背核心考点(六十三)项目组合管理的主要过程DIPP分析

    科科过为您带来软考信息系统项目管理师核心重点考点(六十三)项目组合管理的主要过程&DIPP分析,内含思维导图+真题 [信息系统项目管理师核心考点]项目组合管理的主要过程 1.[评估]项目组合管 ...

  10. 指南-Luat二次开发教程指南-功能开发教程-功耗管理

    目录 功耗管理 简介 常用模块功耗指标 API说明 3种工作模式: 1. 全功能模式 2. 休眠模式 3. 最少功能模式 实现流程 全功能模式 休眠模式 最少功能模式 示例 全功能模式 休眠模式 最少 ...

最新文章

  1. Linux下Tomcat重新启动
  2. 下列不是python对文件的读操作方法是-大工20春《数据挖掘》在线作业1【参考答案】...
  3. matlab安装配置VLFeat库
  4. 23种经典设计模式的java实现_3_桥接模式
  5. excel winform 导入 导出_强大的 Excel 导入导出工具 hutool
  6. dll 源码_重新编译mono——Android动态更新dll
  7. 汉字转换成拼音的代码(asp版)
  8. mysql 安装no key_No package mysql-server available错误解决(centos mysql安装教程)
  9. Dubbo 是如何控制并发数和限流的?
  10. dvbbs 7.1版块图标感应渐变效果 From www.jfeng.cn
  11. 亿能bms上位机_BMS上位机 - 源码下载|Windows编程|通讯编程|源代码 - 源码中国
  12. PHP中的simplehtmldom学习
  13. python win32com 字体选择_用python的win32com模块替换word中的文字搞定批量打印奖状...
  14. Win10极限精简版Tiny10发布:仅占C盘4.3GB
  15. 科普:ARM的授权方式
  16. 【大数据实战】苏宁大数据离线任务开发调度平台实践:设计与开发过程中的要点
  17. linux unlink 函数,linux – unlink和rm有什么区别?
  18. 【C#】System.Linq,万能的查询语句
  19. 玉米社:竞价推广优化怎么做?竞价推广优化技巧
  20. 利用python的docx模块处理word和WPS的docx格式文件

热门文章

  1. VS code入门笔记(一)常用标签介绍
  2. xp启用计算机共享打印机,Win7共享XP打印机设置方法【win7不能共享xp打印机】解决方法...
  3. 思科路由器交换机指示灯状态详解
  4. Talib macd函数探究
  5. java 三维旋转立方体_旋转立方体实现
  6. 预充电电路工作原理_预充电阻和预充继电器的工作原理和功用是什么?
  7. 微信支付服务器白名单,总结下我在微信支付中趟的那些坑。
  8. Android模拟器Root
  9. 飞机精确定位模型matlab,一种精确定位飞机位置的方法与流程
  10. 精读《如何阅读一本书》(附全书思维导图)