⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apus_setup.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
		       "icbi 0,%0 \n\t"		       "isync \n\t"		       : : "r" (addr));		addr += L1_CACHE_BYTES;		length -= L1_CACHE_BYTES;	}	__asm ("dcbf 0,%0\n\t"	       "sync \n\t"	       "icbi 0,%0 \n\t"	       "isync \n\t"	       : : "r" (addr));}/****************************************************** from setup.c */voidapus_restart(char *cmd){	cli();	APUS_WRITE(APUS_REG_LOCK, 		   REGLOCK_BLACKMAGICK1|REGLOCK_BLACKMAGICK2);	APUS_WRITE(APUS_REG_LOCK, 		   REGLOCK_BLACKMAGICK1|REGLOCK_BLACKMAGICK3);	APUS_WRITE(APUS_REG_LOCK, 		   REGLOCK_BLACKMAGICK2|REGLOCK_BLACKMAGICK3);	APUS_WRITE(APUS_REG_SHADOW, REGSHADOW_SELFRESET);	APUS_WRITE(APUS_REG_RESET, REGRESET_AMIGARESET);	for(;;);}voidapus_power_off(void){	for (;;);}voidapus_halt(void){   apus_restart(NULL);}/****************************************************** from setup.c/IDE */#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)/* * IDE stuff. */void ide_insw(ide_ioreg_t port, void *buf, int ns);void ide_outsw(ide_ioreg_t port, void *buf, int ns);voidapus_ide_insw(ide_ioreg_t port, void *buf, int ns){	ide_insw(port, buf, ns);}voidapus_ide_outsw(ide_ioreg_t port, void *buf, int ns){	ide_outsw(port, buf, ns);}intapus_ide_default_irq(ide_ioreg_t base){        return 0;}ide_ioreg_tapus_ide_default_io_base(int index){        return 0;}intapus_ide_check_region(ide_ioreg_t from, unsigned int extent){        return 0;}voidapus_ide_request_region(ide_ioreg_t from,			unsigned int extent,			const char *name){}voidapus_ide_release_region(ide_ioreg_t from,			unsigned int extent){}voidapus_ide_fix_driveid(struct hd_driveid *id){   u_char *p = (u_char *)id;   int i, j, cnt;   u_char t;   if (!MACH_IS_AMIGA && !MACH_IS_MAC)   	return;   for (i = 0; i < num_driveid_types; i++) {      cnt = driveid_types[i] & T_MASK_COUNT;      switch (driveid_types[i] & T_MASK_TYPE) {         case T_CHAR:            p += cnt;            break;         case T_SHORT:            for (j = 0; j < cnt; j++) {               t = p[0];               p[0] = p[1];               p[1] = t;               p += 2;            }            break;         case T_INT:            for (j = 0; j < cnt; j++) {               t = p[0];               p[0] = p[3];               p[3] = t;               t = p[1];               p[1] = p[2];               p[2] = t;               p += 4;            }            break;         case T_TEXT:            for (j = 0; j < cnt; j += 2) {               t = p[0];               p[0] = p[1];               p[1] = t;               p += 2;            }            break;      }   }}__initvoid apus_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, 			       ide_ioreg_t ctrl_port, int *irq){        if (data_port || ctrl_port)                printk("apus_ide_init_hwif_ports: must not be called\n");}#endif/****************************************************** IRQ stuff */__apusstatic unsigned int apus_irq_cannonicalize(unsigned int irq){	return irq;}__apusint apus_get_irq_list(char *buf){#ifdef CONFIG_APUS	extern int amiga_get_irq_list(char *buf);		return amiga_get_irq_list (buf);#else	return 0;#endif}/* IPL must be between 0 and 7 */__apusstatic inline void apus_set_IPL(unsigned long ipl){	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);	APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | ((~ipl) & IPLEMU_IPLMASK));	APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);}__apusstatic inline unsigned long apus_get_IPL(void){	/* This returns the present IPL emulation level. */	unsigned long __f;	APUS_READ(APUS_IPL_EMU, __f);	return ((~__f) & IPLEMU_IPLMASK);}__apusstatic inline unsigned long apus_get_prev_IPL(struct pt_regs* regs){	/* The value saved in mq is the IPL_EMU value at the time of	   interrupt. The lower bits are the current interrupt level,	   the upper bits the requested level. Thus, to restore the	   IPL level to the post-interrupt state, we will need to use	   the lower bits. */	unsigned long __f = regs->mq;	return ((~__f) & IPLEMU_IPLMASK);}#ifdef CONFIG_APUSvoid free_irq(unsigned int irq, void *dev_id){	extern void amiga_free_irq(unsigned int irq, void *dev_id);	amiga_free_irq (irq, dev_id);}int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),	unsigned long irqflags, const char * devname, void *dev_id){	extern int  amiga_request_irq(unsigned int irq, 				      void (*handler)(int, void *, 						      struct pt_regs *),				      unsigned long flags, 				      const char *devname, 				      void *dev_id);	return amiga_request_irq (irq, handler, irqflags, devname, dev_id);}/* In Linux/m68k the sys_request_irq deals with vectors 0-7. That's what   callers expect - but on Linux/APUS we actually use the IRQ_AMIGA_AUTO   vectors (24-31), so we put this dummy function in between to adjust   the vector argument (rather have cruft here than in the generic irq.c). */int sys_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),		    unsigned long irqflags, const char * devname, void *dev_id){	extern int request_sysirq(unsigned int irq, 				  void (*handler)(int, void *, 						  struct pt_regs *),				  unsigned long irqflags,				  const char * devname, void *dev_id);	return request_sysirq(irq+IRQ_AMIGA_AUTO, handler, irqflags, 			      devname, dev_id);}#endif__apusint apus_get_irq(struct pt_regs* regs){#ifdef CONFIG_APUS	int level = apus_get_IPL();#ifdef __INTERRUPT_DEBUG	printk("<%d:%d>", level, apus_get_prev_IPL(regs));#endif	if (0 == level)		return -8;	if (7 == level)		return -9;	return level + IRQ_AMIGA_AUTO;#else	return 0;#endif}__apusvoid apus_post_irq(struct pt_regs* regs, int level){#ifdef __INTERRUPT_DEBUG	printk("{%d}", apus_get_prev_IPL(regs));#endif	/* Restore IPL to the previous value */	apus_set_IPL(apus_get_prev_IPL(regs));}/****************************************************** keyboard */__apusstatic int apus_kbd_setkeycode(unsigned int scancode, unsigned int keycode){	return -EOPNOTSUPP;}__apusstatic int apus_kbd_getkeycode(unsigned int scancode){	return scancode > 127 ? -EINVAL : scancode;}__apusstatic int apus_kbd_translate(unsigned char keycode, unsigned char *keycodep,			      char raw_mode){	*keycodep = keycode;	return 1;}__apusstatic char apus_kbd_unexpected_up(unsigned char keycode){	return 0200;}__apus  static void apus_kbd_leds(unsigned char leds){}__apus  static void apus_kbd_init_hw(void){#ifdef CONFIG_APUS	extern int amiga_keyb_init(void);	amiga_keyb_init();#endif}/****************************************************** debugging *//* some serial hardware definitions */#define SDR_OVRUN   (1<<15)#define SDR_RBF     (1<<14)#define SDR_TBE     (1<<13)#define SDR_TSRE    (1<<12)#define AC_SETCLR   (1<<15)#define AC_UARTBRK  (1<<11)#define SER_DTR     (1<<7)#define SER_RTS     (1<<6)#define SER_DCD     (1<<5)#define SER_CTS     (1<<4)#define SER_DSR     (1<<3)static __inline__ void ser_RTSon(void){    ciab.pra &= ~SER_RTS; /* active low */}__apusint __debug_ser_out( unsigned char c ){	custom.serdat = c | 0x100;	mb();	while (!(custom.serdatr & 0x2000))		barrier();	return 1;}__apusunsigned char __debug_ser_in( void ){	unsigned char c;	/* XXX: is that ok?? derived from amiga_ser.c... */	while( !(custom.intreqr & IF_RBF) )		barrier();	c = custom.serdatr;	/* clear the interrupt, so that another character can be read */	custom.intreq = IF_RBF;	return c;}__apusint __debug_serinit( void ){		unsigned long flags;		save_flags (flags);	cli();	/* turn off Rx and Tx interrupts */	custom.intena = IF_RBF | IF_TBE;	/* clear any pending interrupt */	custom.intreq = IF_RBF | IF_TBE;	restore_flags (flags);	/*	 * set the appropriate directions for the modem control flags,	 * and clear RTS and DTR	 */	ciab.ddra |= (SER_DTR | SER_RTS);   /* outputs */	ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR);  /* inputs */	#ifdef CONFIG_KGDB	/* turn Rx interrupts on for GDB */	custom.intena = IF_SETCLR | IF_RBF;	ser_RTSon();#endif	return 0;}__apusvoid __debug_print_hex(unsigned long x){	int i;	char hexchars[] = "0123456789ABCDEF";	for (i = 0; i < 8; i++) {		__debug_ser_out(hexchars[(x >> 28) & 15]);		x <<= 4;	}	__debug_ser_out('\n');	__debug_ser_out('\r');}__apusvoid __debug_print_string(char* s){	unsigned char c;	while((c = *s++))		__debug_ser_out(c);	__debug_ser_out('\n');	__debug_ser_out('\r');}__apusstatic void apus_progress(char *s, unsigned short value){	__debug_print_string(s);}/****************************************************** init *//* The number of spurious interrupts */volatile unsigned int num_spurious;#define NUM_IRQ_NODES 100static irq_node_t nodes[NUM_IRQ_NODES];extern void (*amiga_default_handler[AUTO_IRQS])(int, void *, struct pt_regs *);static const char *default_names[SYS_IRQS] = {	"spurious int", "int1 handler", "int2 handler", "int3 handler",	"int4 handler", "int5 handler", "int6 handler", "int7 handler"};irq_node_t *new_irq_node(void){	irq_node_t *node;	short i;	for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)		if (!node->handler)			return node;	printk ("new_irq_node: out of nodes\n");	return NULL;}extern void amiga_enable_irq(unsigned int irq);extern void amiga_disable_irq(unsigned int irq);struct hw_interrupt_type amiga_irqctrl = {	" Amiga  ",	NULL,	NULL,	amiga_enable_irq,	amiga_disable_irq,	0,	0};__initvoid apus_init_IRQ(void){	int i;	for ( i = 0 ; i < NR_IRQS ; i++ )		irq_desc[i].handler = &amiga_irqctrl;	for (i = 0; i < NUM_IRQ_NODES; i++)		nodes[i].handler = NULL;	for (i = 0; i < AUTO_IRQS; i++) {		if (amiga_default_handler[i] != NULL)			sys_request_irq(i, amiga_default_handler[i],					0, default_names[i], NULL);	}	amiga_init_IRQ();	int_control.int_sti = __no_use_sti;	int_control.int_cli = __no_use_cli;	int_control.int_save_flags = __no_use_save_flags;	int_control.int_restore_flags = __no_use_restore_flags;}__initvoid apus_init(unsigned long r3, unsigned long r4, unsigned long r5,	       unsigned long r6, unsigned long r7){	extern int parse_bootinfo(const struct bi_record *);	extern char _end[];		/* Parse bootinfo. The bootinfo is located right after           the kernel bss */	parse_bootinfo((const struct bi_record *)&_end);#ifdef CONFIG_BLK_DEV_INITRD	/* Take care of initrd if we have one. Use data from	   bootinfo to avoid the need to initialize PPC	   registers when kernel is booted via a PPC reset. */	if ( ramdisk.addr ) {		initrd_start = (unsigned long) __va(ramdisk.addr);		initrd_end = (unsigned long) 			__va(ramdisk.size + ramdisk.addr);	}#endif /* CONFIG_BLK_DEV_INITRD */	ISA_DMA_THRESHOLD = 0x00ffffff;	ppc_md.setup_arch     = apus_setup_arch;	ppc_md.setup_residual = NULL;	ppc_md.get_cpuinfo    = apus_get_cpuinfo;	ppc_md.irq_cannonicalize = apus_irq_cannonicalize;	ppc_md.init_IRQ       = apus_init_IRQ;	ppc_md.get_irq        = apus_get_irq;	ppc_md.post_irq       = apus_post_irq;#ifdef CONFIG_HEARTBEAT	ppc_md.heartbeat      = apus_heartbeat;	ppc_md.heartbeat_count = 1;#endif#ifdef APUS_DEBUG	__debug_serinit();	ppc_md.progress       = apus_progress;#endif	ppc_md.init           = NULL;	ppc_md.restart        = apus_restart;	ppc_md.power_off      = apus_power_off;	ppc_md.halt           = apus_halt;	ppc_md.time_init      = NULL;	ppc_md.set_rtc_time   = apus_set_rtc_time;	ppc_md.get_rtc_time   = apus_get_rtc_time;	ppc_md.calibrate_decr = apus_calibrate_decr;	ppc_md.nvram_read_val = NULL;	ppc_md.nvram_write_val = NULL;	/* These should not be used for the APUS yet, since it uses	   the M68K keyboard now. */	ppc_md.kbd_setkeycode    = apus_kbd_setkeycode;	ppc_md.kbd_getkeycode    = apus_kbd_getkeycode;	ppc_md.kbd_translate     = apus_kbd_translate;	ppc_md.kbd_unexpected_up = apus_kbd_unexpected_up;	ppc_md.kbd_leds          = apus_kbd_leds;	ppc_md.kbd_init_hw       = apus_kbd_init_hw;#ifdef CONFIG_MAGIC_SYSRQ	ppc_md.kbd_sysrq_xlate	 = NULL;#endif#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)        ppc_ide_md.insw = apus_ide_insw;        ppc_ide_md.outsw = apus_ide_outsw;        ppc_ide_md.default_irq = apus_ide_default_irq;        ppc_ide_md.default_io_base = apus_ide_default_io_base;        ppc_ide_md.ide_check_region = apus_ide_check_region;        ppc_ide_md.ide_request_region = apus_ide_request_region;        ppc_ide_md.ide_release_region = apus_ide_release_region;        ppc_ide_md.fix_driveid = apus_ide_fix_driveid;        ppc_ide_md.ide_init_hwif = apus_ide_init_hwif_ports;        ppc_ide_md.io_base = _IO_BASE;#endif		}/*************************************************** coexistence */void __init adbdev_init(void){}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -