网站开发需要哪些技术宜昌网站建设多少钱
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:33
当前位置: 首页 > news >正文
网站开发需要哪些技术,宜昌网站建设多少钱,星链seo管理,设计网站公司xen-gic初始化流程
调试平台使用的是gic-600#xff0c;建议参考下面的文档来阅读代码#xff0c;搞清楚相关寄存器的功能。 《corelink_gic600_generic_interrupt_controller_technical_reference_manual_100336_0106_00_en》 《IHI0069H_gic_architecture_specification》…xen-gic初始化流程
调试平台使用的是gic-600建议参考下面的文档来阅读代码搞清楚相关寄存器的功能。 《corelink_gic600_generic_interrupt_controller_technical_reference_manual_100336_0106_00_en》 《IHI0069H_gic_architecture_specification》
一、xen-gic代码分析
- core0流程 start_xen……init_traps();WRITE_SYSREG(HCR_AMO | HCR_FMO | HCR_IMO, HCR_EL2); /* 让A/F/I异常都在EL2去执行每个cpu都会这样设置 /…… —init_IRQ(); / 初始化每个中断号的中断描述符信息 /for ( irq 0; irq NR_LOCAL_IRQS; irq ) / NR_LOCAL_IRQS 32这里的local irq是包含了SGI以及PPI /local_irqs_type[irq] IRQ_TYPE_INVALID;init_local_irq_data / 初始化每个local irq的desc结构体从处理流程上看对于gic的每个中断源系统分配一个irq_desc数据结构与之对应 */struct irq_desc desc irq_to_desc(irq);for ( irq 0; irq NR_LOCAL_IRQS; irq ){init_one_irq_desc(desc);desc-status IRQ_DISABLED; / 初始化中断状态 /desc-handler no_irq_type; / 初始化中断处理函数 /cpumask_setall(desc-affinity); / 初始化中断亲和度 /desc-arch.type IRQ_TYPE_INVALID; / 初始化中断类型 /desc-irq irq; / 初始化中断号 /desc-action NULL;desc-arch.type local_irqs_type[irq]; / 初始化中断类型统一设置为IRQ_TYPE_INVALID /}init_irq_data / 初始化流程与init_local_irq_data类似 // NR_LOCAL_IRQS 32NR_IRQ 1024初始化中断号为32~1024的desc结构体 /for ( irq NR_LOCAL_IRQS; irq NR_IRQS; irq ){init_one_irq_desc(desc);desc-irq irq;desc-action NULL;}…… —gic_preinit(); / gic初始化的前期准备 /gic_dt_preinit(); / Find the interrupt controller and set up the callback to translate device tree /device_init(node, DEVICE_GIC, NULL);return desc-init(dev, data); / 调试环境用的是gicv3因此这里执行gicv3_dt_preinit /gicv3_info.hw_version GIC_V3;gicv3_info.node node; / gicv3 dtb节点 /register_gic_ops(gicv3_ops);dt_irq_xlate gic_irq_xlate;……/ Set the GIC as the primary interrupt controller /dt_interrupt_controller node;dt_device_set_used_by(node, DOMID_XEN); / 该gic节点被xen使用 /…… —gic_init();—gic_hw_ops-init(); / 执行gicv3_init /—gicv3_dt_init();dt_device_get_address(node, 0, dbase, NULL); / 获取设备树中关于distributor的mmio地址存放在dbase /gicv3_ioremap_distributor(dbase); / 映射distributor的mmio地址 /gicv3.map_dbase ioremap_nocache(dist_paddr, SZ_64K);if ( !dt_property_read_u32(node, #redistributor-regions, gicv3.rdist_count) )gicv3.rdist_count 1; / sunxi的设备树没有“#redistributor-regions”属性所以这里默认就是1 /for ( i 0; i gicv3.rdist_count; i ){dt_device_get_address(node, 1 i, rdist_base, rdist_size); / 获取gicv3的redistributor的mmio地址 /rdist_regs[i].base rdist_base;rdist_regs[i].size rdist_size;}gicv3.rdist_stride 0; / sunxi的设备树没有“redistributor-stride”属性所以这里默认就是0 /gicv3.rdist_regions rdist_regs; / 保存redistributor的地址信息 /res platform_get_irq(node, 0); / 获取gicv3的Maintenence中断号经过translate /gicv3_info.maintenance_irq res;/ sunxi的phy cpu interface以及virt cpu interface都是使用系统寄存器的方式来实现不走mmio所以下面的代码逻辑无效 /res dt_device_get_address(node, 1 gicv3.rdist_count, cbase, csize);if ( !res )dt_device_get_address(node, 1 gicv3.rdist_count 2, vbase, vsize);—for ( i 0; i gicv3.rdist_count; i )/ 映射redistributor的mmio地址 /gicv3.rdist_regions[i].map_base ioremap_nocache(gicv3.rdist_regions[i].base, gicv3.rdist_regions[i].size);/ 读取Interrupt Controller Type Register的bit23~19(Interrupt identifier bits) /—reg readl_relaxed(GICD GICD_TYPER);—intid_bits GICD_TYPE_ID_BITS(reg); / The maximum number of INTIDs that the GIC implementation supports. /—vgic_v3_setup_hw(dbase, gicv3.rdist_count, gicv3.rdist_regions, intid_bits); / 初始化vgic_v3_hw结构体 /vgic_v3_hw.dbase dbase;……—gicv3_dist_init();writel_relaxed(0, GICD GICD_CTLR); / Disable the distributor */type readl_relaxed(GICD GICD_TYPER);/获取GICD_TYPER的bit4~0(ITLineNumber, Number of SPIs divided by 32表示最大支持的spi数量max num 32(N1)*/nr_lines 32 * ((type GICD_TYPE_LINES) 1);if ( type GICD_TYPE_LPIS )gicv3_lpi_init_host_lpis(GICD_TYPE_ID_BITS(type));/* Only 1020 interrupts are supported /nr_lines min(1020U, nr_lines);gicv3_info.nr_lines nr_lines;printk(GICv3: %d lines, (IID %8.8x).\n, nr_lines, readl_relaxed(GICD GICD_IIDR));/ (XEN) GICv3: 288 lines, (IID 0201643b). // 设置所有的spi中断为低电平触发 // 每个中断有2个bits设置1个寄存器包含16个中断的配置 */for ( i NR_GIC_LOCAL_IRQS; i nr_lines; i 16 )writel_relaxed(0, GICD GICD_ICFGR (i / 16) * 4);/* 配置默认的中断优先级为0xa0每个中断有8个bits设置1个寄存器包含4个中断的配置#define GIC_PRI_LOWEST 0xf0#define GIC_PRI_IRQ 0xa0#define GIC_PRI_IPI 0x90#define GIC_PRI_HIGHEST 0x80 /* Higher priorities belong to Secure-World //for ( i NR_GIC_LOCAL_IRQS; i nr_lines; i 4 ){priority (GIC_PRI_IRQ 24 | GIC_PRI_IRQ 16 | GIC_PRI_IRQ 8 | GIC_PRI_IRQ);writel_relaxed(priority, GICD GICD_IPRIORITYR (i / 4) * 4);}/* 禁用/停用所有spi中断 /for ( i NR_GIC_LOCAL_IRQS; i nr_lines; i 32 ){/ If written, disables forwarding of the corresponding interrupt */writel_relaxed(0xffffffff, GICD GICD_ICENABLER (i / 32) * 4);/* If written, deactivates the corresponding interrupt */writel_relaxed(0xffffffff, GICD GICD_ICACTIVER (i / 32) * 4);}/* 将 SPI 配置为非安全组 1(non-secure Group-1) */for ( i NR_GIC_LOCAL_IRQS; i nr_lines; i 32 )writel_relaxed(GENMASK(31, 0), GICD GICD_IGROUPR (i / 32) * 4);gicv3_dist_wait_for_rwp(); /* 判断前面的寄存器值是否完成写入 // 使能distributor模块 /writel_relaxed(GICD_CTL_ENABLE | GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1, GICD GICD_CTLR);/ Route all global IRQs to this CPU // MPIDR_EL1(Multi-Processor Affinity Register)通常aff0代表在cluster内部的core IDaff1代表cluster ID /affinity gicv3_mpidr_to_affinity(smp_processor_id()); / 读取核号Core ID *//Interrupt_Routing_Mode, bit [31]0b0 Interrupts routed to the PE specified by a.b.c.d. In this routing, a, b, c, and d are thevalues of fields Aff3, Aff2, Aff1, and Aff0 respectively0b1 Interrupts routed to any PE defined as a participating node设置中断只路由到对应的PE/affinity ~GICD_IROUTER_SPI_MODE_ANY;/* 配置GICD_IROUTER寄存器让中断路由到当前core ID对应的核 */for ( i NR_GIC_LOCAL_IRQS; i nr_lines; i )writeq_relaxed(affinity, GICD GICD_IROUTER i * 8);—gicv3_cpu_init();—gicv3_populate_rdist();uint64_t mpidr cpu_logical_map(smp_processor_id()); /* 读取当前core的mpidr寄存器 // 转换mpidr的affinity值为一个32bit数据 */aff (MPIDR_AFFINITY_LEVEL(mpidr, 3) 24 |MPIDR_AFFINITY_LEVEL(mpidr, 2) 16 |MPIDR_AFFINITY_LEVEL(mpidr, 1) 8 |MPIDR_AFFINITY_LEVEL(mpidr, 0));for ( i 0; i gicv3.rdist_count; i ){void iomem ptr gicv3.rdist_regions[i].map_base; / redistributor映射后的虚拟地址 /readl_relaxed(ptr GICR_PIDR2) GIC_PIDR2_ARCH_MASK;do {typer readq_relaxed(ptr GICR_TYPER);/ GICR_TYPER的bits [63:32]与aff进行比较一致则代表当前core与该redistributor是一组的 /if ( (typer 32) aff ){this_cpu(rbase) ptr; / 设置per_cpurbase变量 /if ( typer GICR_TYPER_PLPIS ){rdist_addr gicv3.rdist_regions[i].base;rdist_addr ptr - gicv3.rdist_regions[i].map_base;procnum (typer GICR_TYPER_PROC_NUM_MASK);procnum GICR_TYPER_PROC_NUM_SHIFT;gicv3_set_redist_address(rdist_addr, procnum);this_cpu(lpi_redist).redist_addr address;this_cpu(lpi_redist).redist_id redist_id;gicv3_lpi_init_rdist(ptr);gicv3_lpi_allocate_pendtable(table_reg); / 分配lpi中断的pending table /writeq_relaxed(table_reg, rdist_base GICR_PENDBASER);gicv3_lpi_set_proptable(rdist_base);}}}} —gicv3_enable_redist();s_time_t deadline NOW() MILLISECS(1000);/ 唤醒当前cpu的redistributor */val readl_relaxed(GICD_RDIST_BASE GICR_WAKER);/0b0 This PE is not in, and is not entering, a low power state 0b1 The PE is either in, or is in the process of entering, a low power state/val ~GICR_WAKER_ProcessorSleep;writel_relaxed(val, GICD_RDIST_BASE GICR_WAKER);do {val readl_relaxed(GICD_RDIST_BASE GICR_WAKER);/判断连接的PE是否处于静默状态0b0 An interface to the connected PE might be active.0b1 All interfaces to the connected PE are quiescen/if ( !(val GICR_WAKER_ChildrenAsleep) )break;if ( NOW() deadline ){timeout true;break;}cpu_relax();udelay(1);} while ( timeout );/* 设置PPI(IPI)中断的优先级为0x90 */—priority (GIC_PRI_IPI 24 | GIC_PRI_IPI 16 | GIC_PRI_IPI 8 | GIC_PRI_IPI);for (i 0; i NR_GIC_SGI; i 4)writel_relaxed(priority, GICD_RDIST_SGI_BASE GICR_IPRIORITYR0 (i / 4) * 4);/* 设置SGI中断的优先级为0xa0 */priority (GIC_PRI_IRQ 24 | GIC_PRI_IRQ 16 | GIC_PRI_IRQ 8 | GIC_PRI_IRQ);for (i NR_GIC_SGI; i NR_GIC_LOCAL_IRQS; i 4)writel_relaxed(priority, GICD_RDIST_SGI_BASE GICR_IPRIORITYR0 (i / 4) * 4);/* 设置所有的SGI以及PPI中断为de-activated /writel_relaxed(0xffffffff, GICD_RDIST_SGI_BASE GICR_ICACTIVER0);/ disable所有PPI中断使能所有SGI中断 /writel_relaxed(0xffff0000, GICD_RDIST_SGI_BASE GICR_ICENABLER0); / Interrupt Clear-Enable Register 0 /writel_relaxed(0x0000ffff, GICD_RDIST_SGI_BASE GICR_ISENABLER0); / Interrupt Set-Enable Register 0 // 设置所有的SGI以及PPI中断为非安全组1 /writel_relaxed(GENMASK(31, 0), GICD_RDIST_SGI_BASE GICR_IGROUPR0);gicv3_enable_sre();/ System Register Enable (SRE) // 允许在EL2访问CPU Virtual interface的系统寄存器 /WRITE_SYSREG(val, ICC_SRE_EL2);/ 设置为没有优先级分组 */WRITE_SYSREG(0, ICC_BPR1_EL1);/设置Interrupt Priority Mask寄存器的bit[7:0]为0xff如果中断的优先级比这里设置的值要大的话则cpu或者vcpu interface会拉起irq line通知PE作用类似于一个滤波器/WRITE_SYSREG(DEFAULT_PMR_VALUE, ICC_PMR_EL1);/设置EOI mode需要操作EOI以及DIR寄存器来完成一次中断响应EOI优先级降权DIR中断无效/WRITE_SYSREG(GICC_CTLR_EL1_EOImode_drop, ICC_CTLR_EL1);/* 使能group1的中断 /WRITE_SYSREG(1, ICC_IGRPEN1_EL1);—gicv3_hyp_init();vtr READ_SYSREG(ICH_VTR_EL2); / gic虚拟化特性 /gicv3_info.nr_lrs (vtr ICH_VTR_NRLRGS) 1; / 获取支持的LR registers的数量 /gicv3.nr_priorities ((vtr ICH_VTR_PRIBITS_SHIFT) ICH_VTR_PRIBITS_MASK) 1; / 获取实现的虚拟优先级位数 *//ICH_VMCR_EOI(bit9) 0b1 Virtual EOI mode需要操作EOI以及DIR寄存器来完成一次中断响应ICV_EOIR0_EL1 and ICV_EOIR1_EL1 provide priority drop functionality only. ICV_DIR_EL1 provides interrupt deactivation functionalityICH_VMCR_VENG1(bit1): 0b1 Virtual Group 1 interrupts are enabled/WRITE_SYSREG(ICH_VMCR_EOI | ICH_VMCR_VENG1, ICH_VMCR_EL2); /* 具体含义参照下图 *//Enable. Global enable bit for the virtual CPU interface0b0 Virtual CPU interface operation disabled0b1 Virtual CPU interface operation enable/WRITE_SYSREG(GICH_HCR_EN, ICH_HCR_EL2); /* 使能vcpu interface /—clear_cpu_lr_mask(); / Clear LR mask for cpu0 /this_cpu(lr_mask) 0ULL;…… —init_maintenance_interrupt(); / 注册gic controller的中断服务函数 /request_irq(gic_hw_ops-info-maintenance_irq, 0, maintenance_interrupt, irq-maintenance, NULL);…… —local_irq_enable();/ DAIFClr D, A, I, F Directly clears any of the PSTATE.{D, A, I, F} bits to 0 // 清除PSTATE的相关中断mask bit /asm volatile ( msr daifclr, #2\n ::: memory )2. smp流程 start_xen……for_each_present_cpucpu_up(i)__cpu_up(cpu);arch_cpu_up(cpu);smp_enable_ops[cpu].prepare_cpu(cpu); //多核启动使用psci的方式这里执行call_psci_cpu_on—arm_smccc_smc(psci_cpu_on_nr, cpu_logical_map(cpu), __pa(virt_boot_xen((vaddr_t)init_secondary)), res); init_secondarystart_secondaryinit_traps();WRITE_SYSREG(HCR_AMO | HCR_FMO | HCR_IMO, HCR_EL2); / 让A/F/I异常都在EL2去执行每个cpu都会这样设置 /……gic_init_secondary_cpu();gic_hw_ops-secondary_init(); / 执行gicv3_secondary_cpu_init /—gicv3_secondary_cpu_initgicv3_cpu_init();gicv3_hyp_init();clear_cpu_lr_mask(); / Clear LR mask for secondary cpus */init_secondary_IRQ();init_local_irq_data();local_irq_enable();smp初始化gic的流程和core0的是一致的具体参考上一章节即可。
- 问题 questionanswer1.在xen代码的gicv3_dist_init中把所有的spi中断都路由到了core0那其他的core怎么响应中断呢在注册对应中断的时候会调用gicv3_irq_set_affinity接口重新设置中断路由目前irq_set_affinity使用时设置的cpu都是随机的没有考虑指定cpu 二、dom-gic代码分析
- dom create分支 create_domUs —dt_for_each_child_node(chosen, node){struct domain d;—d domain_create(max_init_domid, d_cfg, flags);arch_domain_create(d, config, flags);……domain_vgic_register(d, count)vgic_v3_init(d, mmio_count);register_vgic_ops(d, v3_ops);domain_vgic_init(d, config-arch.nr_spis); / nr_spis gic_hw_ops-info-nr_lines - 32 // Limit the number of virtual SPIs supported to (1020 - 32) 988 /if ( nr_spis (1020 - NR_LOCAL_IRQS) )return -EINVAL;d-arch.vgic.nr_spis nr_spis;d-arch.vgic.shared_irqs xzalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));d-arch.vgic.pending_irqs xzalloc_array(struct pending_irq, d-arch.vgic.nr_spis);for (i0; id-arch.vgic.nr_spis; i)vgic_init_pending_irq(d-arch.vgic.pending_irqs[i], i 32); / 从32开始赋值给vgic.pending_irqs[i]-irq // SPIs are routed to VCPU0 by default /for ( i 0; i DOMAIN_NR_RANKS(d); i )vgic_rank_init(d-arch.vgic.shared_irqs[i], i 1, 0);d-arch.vgic.handler-domain_init(d); / 执行vgic_v3_domain_init // Allocate memory for Re-distributor regions /rdist_count vgic_v3_max_rdist_count(d);rdist_regions xzalloc_array(struct vgic_rdist_region, rdist_count);d-arch.vgic.nr_regions rdist_count;d-arch.vgic.rdist_regions rdist_regions;radix_tree_init(d-arch.vgic.pend_lpi_tree);if ( domain_use_host_layout(d) ) / 目前使用的是Direct-mapped走这个分支 /{d-arch.vgic.dbase vgic_v3_hw.dbase; / 设置vgic的Distributor基地址 /for ( i 0; i vgic_v3_hw.nr_rdist_regions; i ){d-arch.vgic.rdist_regions[i].base vgic_v3_hw.regions[i].base; / 设置vgic的Redistributor基地址 // Set the first CPU handled by this region /d-arch.vgic.rdist_regions[i].first_cpu first_cpu;}d-arch.vgic.intid_bits vgic_v3_hw.intid_bits;}else……vgic_v3_its_init_domain(d);/ 为Distributor注册mmio处理函数 /register_mmio_handler(d, vgic_distr_mmio_handler, d-arch.vgic.dbase, SZ_64K, NULL);/ 为Redistributor注册mmio处理函数 */for ( i 0; i d-arch.vgic.nr_regions; i ){struct vgic_rdist_region region d-arch.vgic.rdist_regions[i];register_mmio_handler(d, vgic_rdistr_mmio_handler, region-base, region-size, region);}2. domain construct分支 create_domUs……—construct_domU(d, node);……prepare_dtb_domU(d, kinfo);—domain_handle_dtb_bootmodule(d, kinfo);—if ( dt_node_cmp(name, gic) 0 ) / 不存在后续由xen创建虚拟gic节点 /{kinfo-phandle_gic fdt_get_phandle(pfdt, node_next);continue;}—if ( dt_node_cmp(name, passthrough) 0 )scan_pfdt_node(kinfo, pfdt, node_next, DT_ROOT_NODE_ADDR_CELLS_DEFAULT, DT_ROOT_NODE_SIZE_CELLS_DEFAULT, true);—handle_prop_pfdt(kinfo, pfdt, nodeoff, address_cells, size_cells, scan_passthrough_prop);—handle_passthrough_prop(kinfo, xen_reg, xen_path, xen_force, cacheable, address_cells, size_cells);—handle_device_interrupts(kinfo-d, node, true); / 核心 /struct dt_raw_irq rirq;nirq dt_number_of_irq(dev); / 获取中断数量 /for ( i 0; i nirq; i ){dt_device_get_raw_irq(dev, i, rirq);res platform_get_irq(dev, i); / 获取中断号需要调试确认该值 /map_irq_to_domain(d, res, need_mapping, dt_node_name(dev));irq_permit_access(d, irq);vgic_reserve_virq(d, irq);route_irq_to_guest(d, irq, irq, devname); / 将IRQ路由到指定的guest OS /}—make_gic_domU_node(kinfo);make_gicv3_domU_node(kinfo); / 给dom的设备树创建gic节点 /vgic_dist_base(d-arch.vgic);return vgic-vgic_dist_base;dt_child_set_range(cells, GUEST_ROOT_ADDRESS_CELLS, GUEST_ROOT_SIZE_CELLS, vgic_dist_base(d-arch.vgic), GUEST_GICV3_GICD_SIZE);for ( i 0; i d-arch.vgic.nr_regions; i)dt_child_set_range(cells, GUEST_ROOT_ADDRESS_CELLS, GUEST_ROOT_SIZE_CELLS, d-arch.vgic.rdist_regions[i].base, d-arch.vgic.rdist_regions[i].size);}3. distributor的mmio处理 / xen/arch/arm/vgic-v3.c */ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info, register_t r, void priv)int gicd_reg (int)(info-gpa - v-domain-arch.vgic.dbase);switch ( gicd_reg ){case VREG32(GICD_CTLR):{vreg_reg32_update(ctlr, r, info);vreg_reg_update/ Only EnableGrp1A can be changed *//Enable Non-secure Group 1 interrupts0b1 Non-secure Group 1 interrupts are enabled/if ( ctlr GICD_CTLR_ENABLE_G1A )v-domain-arch.vgic.ctlr | GICD_CTLR_ENABLE_G1A;elsev-domain-arch.vgic.ctlr ~GICD_CTLR_ENABLE_G1A; }……case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN): /* 无效 /case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):case VRANGE32(GICD_ICENABLER, GICD_ICENABLERN):case VRANGE32(GICD_ISPENDR, GICD_ISPENDRN):case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN):case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN): / 无效 /case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN): / 无效 /case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):case VRANGE32(GICD_ICFGR, GICD_ICFGRN):/ Above registers are common with GICR and GICD Manage in common /return __vgic_v3_distr_common_mmio_write(vGICD, v, info, gicd_reg, r);……case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):{uint64_t irouter;if ( !vgic_reg64_check_access(dabt) ) goto bad_width;rank vgic_rank_offset(v, 64, gicd_reg - GICD_IROUTER, DABT_DOUBLE_WORD);if ( rank NULL )goto write_ignore;vgic_lock_rank(v, rank, flags);irouter vgic_fetch_irouter(rank, gicd_reg - GICD_IROUTER); / 获取vaff /vreg_reg64_update(irouter, r, info);vgic_store_irouter(v-domain, rank, gicd_reg - GICD_IROUTER, irouter);new_vcpu vgic_v3_irouter_to_vcpu(d, irouter);/** When the Interrupt Route Mode is set, the IRQ targets any vCPUs. For simplicity, the IRQ is always routed to vCPU0./if ( irouter GICD_IROUTER_SPI_MODE_ANY )return d-vcpu[0];vcpu_id vaffinity_to_vcpuid(irouter);if ( vcpu_id d-max_vcpus )return NULL;return d-vcpu[vcpu_id];old_vcpu d-vcpu[read_atomic(rank-vcpu[offset])];/ Only migrate the IRQ if the target vCPU has changed /if ( new_vcpu ! old_vcpu ){if ( vgic_migrate_irq(old_vcpu, new_vcpu, virq) ) / 当前vcpu和旧的vcpu不一致时进行中断迁移 */write_atomic(rank-vcpu[offset], new_vcpu-vcpu_id);}vgic_unlock_rank(v, rank, flags);return 1;}……}4. redistributor的mmio处理 三、涉及到的寄存器 RegisterDisciptionGICD_TYPERRedistributor Type Register提供关于此Redistributor的配置信息GICD_CTLRGICD_IIDRGICD_ICFGRGICD_IPRIORITYRInterrupt Priority Registers保存相应中断的优先级GICD_ICENABLERInterrupt Clear-Enable Registers禁止将相应的中断转发到 CPU 接口GICD_ICACTIVERInterrupt Clear-Active Registers取消相应的中断。这些寄存器用于保存和恢复GIC状态GICD_IGROUPRInterrupt Group Registers控制对应的中断是在Group-0还是Group-1中GICD_IROUTERInterrupt Routing RegistersGICR_PIDR2Peripheral ID2 Register获取GIC版本GICR_PENDBASERGICR_WAKERRedistributor Wake Register允许软件控制与Redistributor对应的WakeRequest电源管理信号的行为ICH_VTR_EL2Interrupt Controller VGIC Type Register记录了支持的GIC虚拟化特性ICH_VMCR_EL2Interrupt Controller Virtual Machine Control Register允许hypervisor保存和恢复虚拟机的GIC stateICH_HCR_EL2Interrupt Controller Hyp Control Register虚拟机环境控制GICR_PIDR2GICR_TYPERGICR_TYPER_PLPISGICR_TYPER_VLPISGICR_TYPER_LASTGICR_WAKERGICR_IPRIORITYR0GICR_ICACTIVER0GICR_ICENABLER0GICR_ISENABLER0GICR_IGROUPR0ICC_SRE_EL2ICC_BPR1_EL1ICC_PMR_EL1ICC_CTLR_EL1ICC_IGRPEN1_EL1ICH_VTR_EL2ICH_VMCR_EL2ICH_HCR_EL2ICV_EOIR0_EL1ICV_DIR_EL1
- 上一篇: 网站开发需要哪些岗位网站建设岗位是干什么的
- 下一篇: 网站开发需要哪些能力网站群系统建设标准
相关文章
-
网站开发需要哪些岗位网站建设岗位是干什么的
网站开发需要哪些岗位网站建设岗位是干什么的
- 技术栈
- 2026年03月21日
-
网站开发需要多长时间网站开发完整项目平台网站开发
网站开发需要多长时间网站开发完整项目平台网站开发
- 技术栈
- 2026年03月21日
-
网站开发需要多长时间佛山专业建站公司
网站开发需要多长时间佛山专业建站公司
- 技术栈
- 2026年03月21日
-
网站开发需要哪些能力网站群系统建设标准
网站开发需要哪些能力网站群系统建设标准
- 技术栈
- 2026年03月21日
-
网站开发需要哪些软件响应式网站自助建设
网站开发需要哪些软件响应式网站自助建设
- 技术栈
- 2026年03月21日
-
网站开发需要哪些证书泉州哪个公司网站做的好
网站开发需要哪些证书泉州哪个公司网站做的好
- 技术栈
- 2026年03月21日
