0
点赞
收藏
分享

微信扫一扫

Qemu源码分析(11)—Apple的学习笔记

暮晨夜雪 2023-10-04 阅读 47

一,前言

昨天了解了qemu中虚拟开发板的内存创建,接着再了解下中断创建和使用。

二,分析

  1. 昨天看了flash初始化,后面的我理解应该一样,接着发现sram初始化后,本来以为和flash是一样的,结果多了如下一句,通过注释也很好理解就是把1个bit展开为了1个byte,这样1M的sram变成了32M空间。

// Bitband the 1 MB from
0x20000000-0x200FFFFF area to
// 32 MB at 0x22000000-0x23FFFFFF.
cortexm_bitband_init(mem_container, "sram-bitband",0x20000000);

此函数中用到一个结构体,通过mmio把MemoryRegion *memory和hwaddr addr关联。

struct
SysBusDevice {
    /*< private >*/
    DeviceState parent_obj;
    /*< public >*/
 
    int num_mmio;
    struct {
        hwaddr addr;
        MemoryRegion *memory;
    } mmio[QDEV_MAX_MMIO];
    int num_pio;
    uint32_t pio[QDEV_MAX_PIO];
};

关键代码

static void
sysbus_mmio_map_common(SysBusDevice *dev, int n, hwaddr addr,bool may_overlap,
int priority)
{
。。。
dev->mmio[n].addr
= addr;
memory_region_add_subregion(get_system_memory(),addr,dev->mmio[n].memory);
。。。
}

  1. 看下中断,peripheral_write_callback是之前初始化注册的,只要调用qemu_set_irq就会触发客户机的中断注册函数进行仿真,主要靠调用irq->handler(irq->opaque, irq->n, level);vcpu的线程调用

gpio_led_irq_handler
qemu_set_irq
cm_irq_set
stm32_gpio_set_odr_irqs
stm32_gpio_update_odr_and_idr
stm32f4_gpio_bsrr_post_write_callback
peripheral_register_write_callback
peripheral_write_callback
memory_region_write_accessor
access_with_adjusted_size
memory_region_dispatch_write
io_writex
io_writew
helper_le_stw_mmu
code_gen_buffer
cpu_tb_exec
cpu_loop_exec_tb
cpu_exec
tcg_cpu_exec
qemu_tcg_cpu_thread_fn

关于vcpu通过TCG生成的代码操作io也就是操作io仿真的内存后,就会调用io_writew,其中peripheral_write_callback也是初始化时候就注册的。PeripheralState里面有MemoryRegion和hwaddr,然后PeripheralState里面还包括了寄存器状态信息,用来操作寄存器值。PeripheralState->PeripheralRegisterState->PeripheralRegisterClass

  1. 中断的初始化及关联

初始化如下

cm_irq_init_in(DEVICE(obj),gpio_led_irq_handler, IRQ_GPIO_LED_IN, 1);

关联到qemu_irq是通过sysbus_connect_irq函数就是关联nvic到gpio。

// Route the ARM CPU_INTERRUPT_HARD to NVIC 0
sysbus_connect_irq(SYS_BUS_DEVICE(cm_state->nvic), 0,
qdev_get_gpio_in(DEVICE(cm_state->cpu), ARM_CPU_IRQ));

关键结构体

struct
NamedGPIOList {
    char *name;
    qemu_irq *in;
    int num_in;
    int num_out;
    QLIST_ENTRY(NamedGPIOList) node;
};

如下是使用的时候通过STM32GPIOState对象找到的中断回调函数。

Qemu源码分析(11)—Apple的学习笔记_qemu

三,小结

Tcg算是解码的核心,客户实现不同芯片语言的翻译,但是这部分我并不想关注,主要就是了解怎么进入中断的,基本就是识别到内存变换,然后通过地址找到对象,最后找到关联的回调函数进行功能实现。当前之前需要先进行对象的初始化及qemu_irq的回调函数注册。


举报

相关推荐

0 条评论