免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4815 | 回复: 1
打印 上一主题 下一主题

请大家分析一下define_machine宏 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-03-10 00:07 |只看该作者 |倒序浏览
define_machine定义为:
include/asm-powerpc/machdep.h

#define __machine_desc __attribute__ ((__section__ (".machine.desc"))

#define define_machine(name)                                    \
        extern struct machdep_calls mach_##name;                \
        EXPORT_SYMBOL(mach_##name);                             \
        struct machdep_calls mach_##name __machine_desc =

它的使用,比如:
arch/powerpc/platforms/chrp/setup.c

define_machine(chrp) {
        .name                   = "CHRP",
        .probe                  = chrp_probe,
        .setup_arch             = chrp_setup_arch,
        .init                   = chrp_init2,
        .show_cpuinfo           = chrp_show_cpuinfo,
        .init_IRQ               = chrp_init_IRQ,
        .restart                = rtas_restart,
        .power_off              = rtas_power_off,
        .halt                   = rtas_halt,
        .time_init              = chrp_time_init,
        .set_rtc_time           = chrp_set_rtc_time,
        .get_rtc_time           = chrp_get_rtc_time,
        .calibrate_decr         = generic_calibrate_decr,
        .phys_mem_access_prot   = pci_phys_mem_access_prot,
};

而这些函数是以ppc_md的成员出现的,ppc_md定义为:
arch/powerpc/kernel/setup-common.c

struct machdep_calls ppc_md;
EXPORT_SYMBOL(ppc_md);

--------------------------------------------------------------------------------------
请问两者是怎么联系在一起的?

在老的ppc目录下,使用一个platform_init的函数来进行,比如:
arch/ppc/platforms/sandpoint.c

void __init
platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                unsigned long r6, unsigned long r7)
{
        parse_bootinfo(find_bootinfo());

        /* ASSUMPTION:  If both r3 (bd_t pointer) and r6 (cmdline pointer)
         * are non-zero, then we should use the board info from the bd_t
         * structure and the cmdline pointed to by r6 instead of the
         * information from birecs, if any.  Otherwise, use the information
         * from birecs as discovered by the preceding call to
         * parse_bootinfo().  This rule should work with both PPCBoot, which
         * uses a bd_t board info structure, and the kernel boot wrapper,
         * which uses birecs.
         */
        if (r3 && r6) {
                /* copy board info structure */
                memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
                /* copy command line */
                *(char *)(r7+KERNELBASE) = 0;
                strcpy(cmd_line, (char *)(r6+KERNELBASE));
        }

#ifdef CONFIG_BLK_DEV_INITRD
        /* take care of initrd if we have one */
        if (r4) {
                initrd_start = r4 + KERNELBASE;
                initrd_end = r5 + KERNELBASE;
        }
#endif /* CONFIG_BLK_DEV_INITRD */

        /* Map in board regs, etc. */
        sandpoint_set_bat();

        isa_io_base = MPC10X_MAPB_ISA_IO_BASE;
        isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE;
        pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET;
        ISA_DMA_THRESHOLD = 0x00ffffff;
        DMA_MODE_READ = 0x44;
        DMA_MODE_WRITE = 0x48;
        ppc_do_canonicalize_irqs = 1;

        ppc_md.setup_arch = sandpoint_setup_arch;
        ppc_md.show_cpuinfo = sandpoint_show_cpuinfo;
        ppc_md.init_IRQ = sandpoint_init_IRQ;
        ppc_md.get_irq = openpic_get_irq;

        ppc_md.restart = sandpoint_restart;
        ppc_md.power_off = sandpoint_power_off;
        ppc_md.halt = sandpoint_halt;

        ppc_md.find_end_of_memory = sandpoint_find_end_of_memory;
        ppc_md.setup_io_mappings = sandpoint_map_io;

        TODC_INIT(TODC_TYPE_PC97307, 0x70, 0x00, 0x71, ;
       ppc_md.time_init = todc_time_init;
        ppc_md.set_rtc_time = todc_set_rtc_time;
        ppc_md.get_rtc_time = todc_get_rtc_time;
        ppc_md.calibrate_decr = todc_calibrate_decr;

        ppc_md.nvram_read_val = todc_mc146818_read_val;
        ppc_md.nvram_write_val = todc_mc146818_write_val;

#ifdef CONFIG_KGDB
        ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
#endif
#ifdef CONFIG_SERIAL_TEXT_DEBUG
        ppc_md.progress = gen550_progress;
#endif

#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
        ppc_ide_md.default_irq = sandpoint_ide_default_irq;
        ppc_ide_md.default_io_base = sandpoint_ide_default_io_base;
        ppc_ide_md.ide_init_hwif = sandpoint_ide_init_hwif_ports;
#endif
}

谢谢

论坛徽章:
0
2 [报告]
发表于 2008-07-22 10:59 |只看该作者
arch/powerpc/kernel/setup-common.c
void probe_machine(void)里面有一段:
for(machine_id = .....)
{
     memcpy(&ppc_md, machine_id,sizeof(struct machdep_calls));
}

而此时的machine_id指针正是指向了arch/powerpc/platforms/.../....c里的
define_machine(...)
{
   ...
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP