📄 chrp_setup.c
字号:
static void __chrpbriq_restart(char *cmd){ cli(); if (briq_SPOR) out_be32(briq_SPOR, 0); for(;;) ;}/* * Finds the open-pic node and sets OpenPIC_Addr based on its reg property. * Then checks if it has an interrupt-ranges property. If it does then * we have a distributed open-pic, so call openpic_set_sources to tell * the openpic code where to find the interrupt source registers. */static void __init chrp_find_openpic(void){ struct device_node *np; int len, i; unsigned int *iranges; void *isu; np = find_type_devices("open-pic"); if (np == NULL || np->n_addrs == 0) return; printk(KERN_INFO "OpenPIC at %x (size %x)\n", np->addrs[0].address, np->addrs[0].size); OpenPIC_Addr = ioremap(np->addrs[0].address, 0x40000); if (OpenPIC_Addr == NULL) { printk(KERN_ERR "Failed to map OpenPIC!\n"); return; } iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); if (iranges == NULL || len < 2 * sizeof(unsigned int)) return; /* not distributed */ /* * The first pair of cells in interrupt-ranges refers to the * IDU; subsequent pairs refer to the ISUs. */ len /= 2 * sizeof(unsigned int); if (np->n_addrs < len) { printk(KERN_ERR "Insufficient addresses for distributed" " OpenPIC (%d < %d)\n", np->n_addrs, len); return; } if (iranges[1] != 0) { printk(KERN_INFO "OpenPIC irqs %d..%d in IDU\n", iranges[0], iranges[0] + iranges[1] - 1); openpic_set_sources(iranges[0], iranges[1], NULL); } for (i = 1; i < len; ++i) { iranges += 2; printk(KERN_INFO "OpenPIC irqs %d..%d in ISU at %x (%x)\n", iranges[0], iranges[0] + iranges[1] - 1, np->addrs[i].address, np->addrs[i].size); isu = ioremap(np->addrs[i].address, np->addrs[i].size); if (isu != NULL) openpic_set_sources(iranges[0], iranges[1], isu); else printk(KERN_ERR "Failed to map OpenPIC ISU at %x!\n", np->addrs[i].address); }}static void __initchrp_init_irq_openpic(unsigned long intack){ int i; unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; chrp_find_openpic(); prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); OpenPIC_InitSenses = init_senses; OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; openpic_init(NUM_8259_INTERRUPTS); /* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */ openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", i8259_irq); for (i = 0; i < NUM_8259_INTERRUPTS; i++) irq_desc[i].handler = &i8259_pic; i8259_init(intack);}static void __initchrp_init_irq_8259(unsigned long intack){ int i; ppc_md.get_irq = i8259_irq; for (i = 0; i < NUM_8259_INTERRUPTS; i++) irq_desc[i].handler = &i8259_pic; i8259_init(intack);}void __init chrp_init_IRQ(void){ struct device_node *np; unsigned long intack = 0; struct device_node *main_irq_ctrler = NULL;#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) struct device_node *kbd;#endif for (np = find_devices("pci"); np != NULL; np = np->next) { unsigned int *addrp = (unsigned int *) get_property(np, "8259-interrupt-acknowledge", NULL); if (addrp == NULL) continue; intack = addrp[prom_n_addr_cells(np)-1]; break; } if (np == NULL) printk("Cannot find pci to get ack address\n"); /* Look for the node of the toplevel interrupt controller. * If we don't find it, we assume openpic */ np = find_path_device("/chosen"); if (np) { phandle *irq_ctrler_ph = (phandle *)get_property(np, "interrupt-controller", NULL); if (irq_ctrler_ph) main_irq_ctrler = find_phandle(*irq_ctrler_ph); } if (main_irq_ctrler && device_is_compatible(main_irq_ctrler, "8259")) chrp_init_irq_8259(intack); else chrp_init_irq_openpic(intack);#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) /* see if there is a keyboard in the device tree with a parent of type "adb" */ for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) if (kbd->parent && kbd->parent->type && strcmp(kbd->parent->type, "adb") == 0) break; if (kbd) request_irq(HYDRA_INT_ADB_NMI, xmon_irq, 0, "XMON break", 0);#endif}void __initchrp_init2(void){ if (is_briq) briq_SPOR = (unsigned int *)ioremap(0xff0000e8, 4);#ifdef CONFIG_NVRAM /* Fix me: currently, a lot of pmac_nvram routines are marked __pmac, and * blindly calling pmac_nvram_init() on chrp cause bad results. * Among others, it cracks on briQ. * Please implement a CHRP specific version. --BenH */ if (!is_briq) pmac_nvram_init();#endif /* This is to be replaced by RTAS when available */ request_region(0x20,0x20,"pic1"); request_region(0xa0,0x20,"pic2"); request_region(0x00,0x20,"dma1"); request_region(0x40,0x20,"timer"); request_region(0x80,0x10,"dma page reg"); request_region(0xc0,0x20,"dma2"); if (ppc_md.progress) ppc_md.progress(" Have fun! ", 0x7777);#if defined(CONFIG_VT) && (defined(CONFIG_ADB_KEYBOARD) || defined(CONFIG_INPUT)) /* see if there is a keyboard in the device tree with a parent of type "adb" */ { struct device_node *kbd; for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) { if (kbd->parent && kbd->parent->type && strcmp(kbd->parent->type, "adb") == 0) { select_adb_keyboard(); break; } } }#endif /* CONFIG_VT && (CONFIG_ADB_KEYBOARD || CONFIG_INPUT) */}#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)static void __chrpchrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq){ ide_ioreg_t reg = data_port; int i; for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hw->io_ports[i] = reg; reg += 1; } hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;}#endifvoid __initchrp_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7){ struct device_node *root = find_path_device("/"); char *machine;#ifdef CONFIG_BLK_DEV_INITRD /* take care of initrd if we have one */ if ( r6 ) { initrd_start = r6 + KERNELBASE; initrd_end = r6 + r7 + KERNELBASE; }#endif /* CONFIG_BLK_DEV_INITRD */ ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; isa_io_base = CHRP_ISA_IO_BASE; /* default value */ /* Check if it's a briq */ machine = get_property(root, "model", NULL); is_briq = machine && strncmp(machine, "TotalImpact,BRIQ-1", 18) == 0; ppc_md.setup_arch = chrp_setup_arch; ppc_md.show_percpuinfo = of_show_percpuinfo; ppc_md.show_cpuinfo = chrp_show_cpuinfo; ppc_md.irq_cannonicalize = chrp_irq_cannonicalize; ppc_md.init_IRQ = chrp_init_IRQ; ppc_md.get_irq = openpic_get_irq; ppc_md.init = chrp_init2; ppc_md.restart = is_briq ? briq_restart : chrp_restart; ppc_md.power_off = chrp_power_off; ppc_md.halt = chrp_halt; ppc_md.time_init = chrp_time_init; ppc_md.set_rtc_time = chrp_set_rtc_time; ppc_md.get_rtc_time = chrp_get_rtc_time; ppc_md.calibrate_decr = chrp_calibrate_decr; ppc_md.find_end_of_memory = pmac_find_end_of_memory;#ifdef CONFIG_VT /* these are adjusted in chrp_init2 if we have an ADB keyboard */ ppc_md.kbd_setkeycode = pckbd_setkeycode; ppc_md.kbd_getkeycode = pckbd_getkeycode; ppc_md.kbd_translate = pckbd_translate; ppc_md.kbd_unexpected_up = pckbd_unexpected_up; ppc_md.kbd_leds = pckbd_leds; ppc_md.kbd_init_hw = pckbd_init_hw;#ifdef CONFIG_MAGIC_SYSRQ ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; SYSRQ_KEY = 0x54;#endif /* CONFIG_MAGIC_SYSRQ */#endif /* CONFIG_VT */ if (rtas_data) { struct device_node *rtas; unsigned int *p; rtas = find_devices("rtas"); if (rtas != NULL) { if (get_property(rtas, "display-character", NULL)) { ppc_md.progress = rtas_display_progress; p = (unsigned int *) get_property (rtas, "ibm,display-line-length", NULL); if (p) max_width = *p; } else if (get_property(rtas, "set-indicator", NULL)) ppc_md.progress = rtas_indicator_progress; } }#ifdef CONFIG_BOOTX_TEXT if (ppc_md.progress == NULL && boot_text_mapped) ppc_md.progress = btext_progress;#endif#ifdef CONFIG_SMP ppc_md.smp_ops = &chrp_smp_ops;#endif /* CONFIG_SMP */#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports;#endif /* * Print the banner, then scroll down so boot progress * can be printed. -- Cort */ if ( ppc_md.progress ) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);}void __chrprtas_display_progress(char *s, unsigned short hex){ int width; char *os = s; if ( call_rtas( "display-character", 1, 1, NULL, '\r' ) ) return; width = max_width; while ( *os ) { if ( (*os == '\n') || (*os == '\r') ) width = max_width; else width--; call_rtas( "display-character", 1, 1, NULL, *os++ ); /* if we overwrite the screen length */ if ( width == 0 ) while ( (*os != 0) && (*os != '\n') && (*os != '\r') ) os++; } /*while ( width-- > 0 )*/ call_rtas( "display-character", 1, 1, NULL, ' ' );}void __chrprtas_indicator_progress(char *s, unsigned short hex){ call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex);}#ifdef CONFIG_BOOTX_TEXTvoidbtext_progress(char *s, unsigned short hex){ prom_print(s); prom_print("\n");}#endif /* CONFIG_BOOTX_TEXT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -