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

📄 apus_setup.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************** CACHE */#define L1_CACHE_BYTES 32#define MAX_CACHE_SIZE 8192void cache_push(__u32 addr, int length){	addr = mm_ptov(addr);	if (MAX_CACHE_SIZE < length)		length = MAX_CACHE_SIZE;	while(length > 0){		__asm ("dcbf 0,%0\n\t"		       : : "r" (addr));		addr += L1_CACHE_BYTES;		length -= L1_CACHE_BYTES;	}	/* Also flush trailing block */	__asm ("dcbf 0,%0\n\t"	       "sync \n\t"	       : : "r" (addr));}void cache_clear(__u32 addr, int length){	if (MAX_CACHE_SIZE < length)		length = MAX_CACHE_SIZE;	addr = mm_ptov(addr);	__asm ("dcbf 0,%0\n\t"	       "sync \n\t"	       "icbi 0,%0 \n\t"	       "isync \n\t"	       : : "r" (addr));	addr += L1_CACHE_BYTES;	length -= L1_CACHE_BYTES;	while(length > 0){		__asm ("dcbf 0,%0\n\t"		       "sync \n\t"		       "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);}/****************************************************** IRQ stuff */static unsigned char last_ipl[8];int apus_get_irq(struct pt_regs* regs){	unsigned char ipl_emu, mask;	unsigned int level;	APUS_READ(APUS_IPL_EMU, ipl_emu);	level = (ipl_emu >> 3) & IPLEMU_IPLMASK;	mask = IPLEMU_SETRESET|IPLEMU_DISABLEINT|level;	level ^= 7;	/* Save previous IPL value */	if (last_ipl[level])		return -2;	last_ipl[level] = ipl_emu;	/* Set to current IPL value */	APUS_WRITE(APUS_IPL_EMU, mask);	APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT|level);#ifdef __INTERRUPT_DEBUG	printk("<%d:%d>", level, ~ipl_emu & IPLEMU_IPLMASK);#endif	return level + IRQ_AMIGA_AUTO;}void apus_end_irq(unsigned int irq){	unsigned char ipl_emu;	unsigned int level = irq - IRQ_AMIGA_AUTO;#ifdef __INTERRUPT_DEBUG	printk("{%d}", ~last_ipl[level] & IPLEMU_IPLMASK);#endif	/* Restore IPL to the previous value */	ipl_emu = last_ipl[level] & IPLEMU_IPLMASK;	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET|IPLEMU_DISABLEINT|ipl_emu);	last_ipl[level] = 0;	ipl_emu ^= 7;	APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT|ipl_emu);}/****************************************************** keyboard */static int apus_kbd_setkeycode(unsigned int scancode, unsigned int keycode){	return -EOPNOTSUPP;}static int apus_kbd_getkeycode(unsigned int scancode){	return scancode > 127 ? -EINVAL : scancode;}static char apus_kbd_unexpected_up(unsigned char keycode){	return 0200;}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 */}int __debug_ser_out( unsigned char c ){	custom.serdat = c | 0x100;	mb();	while (!(custom.serdatr & 0x2000))		barrier();	return 1;}unsigned 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;}int __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;}void __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');}void __debug_print_string(char* s){	unsigned char c;	while((c = *s++))		__debug_ser_out(c);	__debug_ser_out('\n');	__debug_ser_out('\r');}static void apus_progress(char *s, unsigned short value){	__debug_print_string(s);}/****************************************************** init *//* The number of spurious interrupts */volatile unsigned int num_spurious;extern struct irqaction amiga_sys_irqaction[AUTO_IRQS];extern void amiga_enable_irq(unsigned int irq);extern void amiga_disable_irq(unsigned int irq);struct hw_interrupt_type amiga_sys_irqctrl = {	typename: "Amiga IPL",	end: apus_end_irq,};struct hw_interrupt_type amiga_irqctrl = {	typename: "Amiga    ",	enable: amiga_enable_irq,	disable: amiga_disable_irq,};#define HARDWARE_MAPPED_SIZE (512*1024)unsigned long __init apus_find_end_of_memory(void){	int shadow = 0;	unsigned long total;	/* The memory size reported by ADOS excludes the 512KB	   reserved for PPC exception registers and possibly 512KB	   containing a shadow of the ADOS ROM. */	{		unsigned long size = memory[0].size;		/* If 2MB aligned, size was probably user                   specified. We can't tell anything about shadowing                   in this case so skip shadow assignment. */		if (0 != (size & 0x1fffff)){			/* Align to 512KB to ensure correct handling			   of both memfile and system specified			   sizes. */			size = ((size+0x0007ffff) & 0xfff80000);			/* If memory is 1MB aligned, assume                           shadowing. */			shadow = !(size & 0x80000);		}		/* Add the chunk that ADOS does not see. by aligning                   the size to the nearest 2MB limit upwards.  */		memory[0].size = ((size+0x001fffff) & 0xffe00000);	}	total = memory[0].size;	/* Remove the memory chunks that are controlled by special           Phase5 hardware. */	/* Remove the upper 512KB if it contains a shadow of	   the ADOS ROM. FIXME: It might be possible to	   disable this shadow HW. Check the booter	   (ppc_boot.c) */	if (shadow)		total -= HARDWARE_MAPPED_SIZE;	/* Remove the upper 512KB where the PPC exception	   vectors are mapped. */	total -= HARDWARE_MAPPED_SIZE;	/* Linux/APUS only handles one block of memory -- the one on	   the PowerUP board. Other system memory is horrible slow in	   comparison. The user can use other memory for swapping	   using the z2ram device. */	ram_phys_base = memory[0].addr;	return total;}static void __initapus_map_io(void){	/* Map PPC exception vectors. */	io_block_mapping(0xfff00000, 0xfff00000, 0x00020000, _PAGE_KERNEL);	/* Map chip and ZorroII memory */	io_block_mapping(zTwoBase,   0x00000000, 0x01000000, _PAGE_IO);}__initvoid apus_init_IRQ(void){	struct irqaction *action;	int i;#ifdef CONFIG_PCI        apus_setup_pci_ptrs();#endif	for ( i = 0 ; i < AMI_IRQS; i++ ) {		irq_desc[i].status = IRQ_LEVEL;		if (i < IRQ_AMIGA_AUTO) {			irq_desc[i].handler = &amiga_irqctrl;		} else {			irq_desc[i].handler = &amiga_sys_irqctrl;			action = &amiga_sys_irqaction[i-IRQ_AMIGA_AUTO];			if (action->name)				setup_irq(i, action);		}	}	amiga_init_IRQ();}__initvoid platform_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.show_cpuinfo   = apus_show_cpuinfo;	ppc_md.init_IRQ       = apus_init_IRQ;	ppc_md.get_irq        = apus_get_irq;#ifdef CONFIG_HEARTBEAT	ppc_md.heartbeat      = apus_heartbeat;	heartbeat_reset(0)    = 1;		/* assume UP for now */	heartbeat_count(0)    = 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.find_end_of_memory = apus_find_end_of_memory;	ppc_md.setup_io_mappings = apus_map_io;	/* 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     = amiga_kbd_translate;	ppc_md.kbd_unexpected_up = apus_kbd_unexpected_up;	ppc_md.kbd_init_hw       = apus_kbd_init_hw;#ifdef CONFIG_SYSRQ	ppc_md.ppc_kbd_sysrq_xlate = amiga_sysrq_xlate;	SYSRQ_KEY                = 0xff;#endif}

⌨️ 快捷键说明

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