Date: Sun, 24 May 1998 20:00:48 +0100
From: Jesper Skov <jskov@cygnus.co.uk>
To: linux-m68k@lists.linux-m68k.org
Subject: L68K: Linux/APUS changes
Sender: owner-linux-m68k@phil.uni-sb.de

hi


These changes are relative to Linux/m68k-2.1.101. I have also
committed these changes to the vger tree (read: I will send another
vger-relative patch to Geert :)

The fb/console and serial changes are from Roman Zippel.

JEsper

diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/arch/m68k/amiga/amiints.c ./arch/m68k/amiga/amiints.c
--- /home/jskov/kernel/dist/linux-2.1.101/arch/m68k/amiga/amiints.c	Sat Jan 24 19:09:30 1998
+++ ./arch/m68k/amiga/amiints.c	Sun May 17 20:43:33 1998
@@ -32,6 +32,12 @@
 #include <asm/traps.h>
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
+#ifdef CONFIG_APUS
+#include <asm/amigappc.h>
+/* Rename a few functions. */
+#define amiga_request_irq request_irq
+#define amiga_free_irq free_irq
+#endif
 
 extern int cia_request_irq(struct ciabase *base,int irq,
                            void (*handler)(int, void *, struct pt_regs *),
@@ -89,9 +95,16 @@
 	for (i = 0; i < AMI_IRQS; i++)
 		ami_ablecount[i] = 0;
 
-	/* turn off all interrupts and enable the master interrupt bit */
+	/* turn off all interrupts... */
 	custom.intena = 0x7fff;
 	custom.intreq = 0x7fff;
+
+#ifdef CONFIG_APUS
+	APUS_WRITE(APUS_REG_INT, REGINT_INTMASTER | REGINT_ENABLEIPL);
+	APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_IPLMASK);
+#endif
+	/* ... and enable the master interrupt bit */
 	custom.intena = IF_SETCLR | IF_INTEN;
 
 	cia_init_IRQ(&ciaa_base);
@@ -353,8 +366,16 @@
 		server->count--;
 		return;
 	}
+#ifdef CONFIG_APUS
+	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
+	APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
+	APUS_WRITE(APUS_IPL_EMU, (IPLEMU_SETRESET
+				  | (~(fp->mq) & IPLEMU_IPLMASK)));
+	APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+#else
 	save_flags(flags);
 	restore_flags((flags & ~0x0700) | (fp->sr & 0x0700));
+#endif
 	/* if slow handlers exists, serve them now */
 	slow_nodes = node;
 	for (;;) {
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/arch/m68k/amiga/config.c ./arch/m68k/amiga/config.c
--- /home/jskov/kernel/dist/linux-2.1.101/arch/m68k/amiga/config.c	Tue Apr  7 12:02:32 1998
+++ ./arch/m68k/amiga/config.c	Sun May 17 20:57:57 1998
@@ -31,6 +31,10 @@
 #include <asm/machdep.h>
 #include <linux/zorro.h>
 
+#ifdef CONFIG_APUS
+#include <asm/io.h>
+#endif
+
 unsigned long amiga_model;
 unsigned long amiga_eclock;
 unsigned long amiga_masterclock;
@@ -344,10 +348,12 @@
   mach_kbdrate         = amiga_kbdrate;
   mach_init_IRQ        = amiga_init_IRQ;
   mach_default_handler = &amiga_default_handler;
+#ifndef CONFIG_APUS
   mach_request_irq     = amiga_request_irq;
   mach_free_irq        = amiga_free_irq;
   enable_irq           = amiga_enable_irq;
   disable_irq          = amiga_disable_irq;
+#endif
   mach_get_model       = amiga_get_model;
   mach_get_hardware_list = amiga_get_hardware_list;
   mach_get_irq_list    = amiga_get_irq_list;
@@ -713,6 +719,7 @@
 
 static void amiga_reset (void)
 {
+#ifdef __mc68000__
   unsigned long jmp_addr040 = VTOP(&&jmp_addr_label040);
   unsigned long jmp_addr = VTOP(&&jmp_addr_label);
 
@@ -770,9 +777,9 @@
      "1:\n\t"
      "reset\n\t"
      "jmp   %/a0@" : /* Just that gcc scans it for % escapes */ );
+#endif  
   
   for (;;);
-
 }
 
 
@@ -815,9 +822,17 @@
 
 static void amiga_serial_putc(char c)
 {
-    custom.serdat = (unsigned char)c | 0x100;
-    while (!(custom.serdatr & 0x2000))
-	;
+	custom.serdat = (unsigned char)c | 0x100;
+
+#ifdef CONFIG_APUS
+	/* I'm sure this should not be necessary since the address is
+	   marked non-cachable and coherent. Still, without it the
+	   serial output is not usable. -jskov */
+	eieio ();
+#endif
+
+	while (!(custom.serdatr & 0x2000))
+		;
 }
 
 void amiga_serial_console_write(struct console *co, const char *s,
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/arch/m68k/kernel/ints.c ./arch/m68k/kernel/ints.c
--- /home/jskov/kernel/dist/linux-2.1.101/arch/m68k/kernel/ints.c	Wed Feb  4 15:51:03 1998
+++ ./arch/m68k/kernel/ints.c	Mon May 18 09:18:33 1998
@@ -37,8 +37,20 @@
 #include <asm/page.h>
 #include <asm/machdep.h>
 
+#ifdef CONFIG_APUS
+/* Rename a few functions to avoid conflicts. */
+#define request_irq nop_request_irq
+#define free_irq nop_free_irq
+#define enable_irq nop_enable_irq
+#define disable_irq nop_disable_irq
+#define probe_irq_on nop_probe_irq_on
+#define probe_irq_off nop_probe_irq_off
+#define init_IRQ apus_init_IRQ
+#endif
+
 /* table for system interrupt handlers */
-static irq_handler_t irq_list[SYS_IRQS];
+/* Cannot be static. Also accessed by ppc code. -jskov */
+irq_handler_t irq_list[SYS_IRQS];
 
 static const char *default_names[SYS_IRQS] = {
 	"spurious int", "int1 handler", "int2 handler", "int3 handler",
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/arch/m68k/kernel/kgdb.c ./arch/m68k/kernel/kgdb.c
--- /home/jskov/kernel/dist/linux-2.1.101/arch/m68k/kernel/kgdb.c	Tue Jan  6 13:57:26 1998
+++ ./arch/m68k/kernel/kgdb.c	Sun May 17 15:02:48 1998
@@ -236,8 +236,8 @@
 static unsigned char atari_scc_intr( void );
 #endif
 #ifdef CONFIG_AMIGA
-static int amiga_ser_out( unsigned char c );
-static unsigned char amiga_ser_in( void );
+extern int amiga_ser_out( unsigned char c );
+extern unsigned char amiga_ser_in( void );
 #endif
 
 /************************* End of Prototypes **************************/
@@ -1192,35 +1192,3 @@
 }
 
 #endif
-
-
-/* -------------------- Amiga serial I/O -------------------- */
-
-#ifdef CONFIG_AMIGA
-
-static int amiga_ser_out( unsigned char c )
-
-{
-	custom.serdat = c | 0x100;
-	while (!(custom.serdatr & 0x2000))
-		barrier();
-	return( 1 );
-}
-
-
-static unsigned char amiga_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( 0 );
-}
-
-#endif
-
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/arch/m68k/kernel/setup.c ./arch/m68k/kernel/setup.c
--- /home/jskov/kernel/dist/linux-2.1.101/arch/m68k/kernel/setup.c	Sun May 17 14:35:00 1998
+++ ./arch/m68k/kernel/setup.c	Sun May 24 18:02:39 1998
@@ -30,6 +30,13 @@
 #ifdef CONFIG_ATARI
 #include <asm/atarihw.h>
 #endif
+#ifdef CONFIG_APUS
+#include <asm/mmu.h>
+/* Rename a few functions. */
+#define setup_arch apus_setup_arch
+#define get_cpuinfo apus_get_cpuinfo
+#define check_bugs nop_check_bugs
+#endif
 
 #ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/blk.h>
@@ -49,7 +56,7 @@
 int m68k_num_memory = 0;
 struct mem_info m68k_memory[NUM_MEMINFO];
 
-static struct mem_info m68k_ramdisk = { 0, 0 };
+struct mem_info m68k_ramdisk = { 0, 0 };
 
 static char m68k_command_line[CL_SIZE];
 char saved_command_line[CL_SIZE];
@@ -107,7 +114,7 @@
 #define MASK_256K 0xfffc0000
 
 
-__initfunc(static void m68k_parse_bootinfo(const struct bi_record *record))
+__initfunc(void m68k_parse_bootinfo(const struct bi_record *record))
 {
     while (record->tag != BI_LAST) {
 	int unknown = 0;
@@ -163,6 +170,7 @@
 	int i;
 	char *p, *q;
 
+#ifdef __mc68000__
 	/* The bootinfo is located right after the kernel bss */
 	m68k_parse_bootinfo((const struct bi_record *)&_end);
 
@@ -178,11 +186,14 @@
 		volatile int zero = 0;
 		asm __volatile__ ("frestore %0" : : "m" (zero));
 	}
+#endif
 
+#ifndef CONFIG_APUS
 	init_task.mm->start_code = PAGE_OFFSET;
 	init_task.mm->end_code = (unsigned long) &_etext;
 	init_task.mm->end_data = (unsigned long) &_edata;
 	init_task.mm->brk = (unsigned long) &_end;
+#endif
 
 	*cmdline_p = m68k_command_line;
 	memcpy(saved_command_line, *cmdline_p, CL_SIZE);
@@ -267,10 +278,12 @@
 	}
 #endif
 
+#ifndef CONFIG_APUS
 	*memory_start_p = availmem;
 	*memory_end_p = 0;
 	for (i = 0; i < m68k_num_memory; i++)
 		*memory_end_p += m68k_memory[i].size & MASK_256K;
+#endif
 }
 
 int get_cpuinfo(char * buffer)
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/drivers/block/ide-probe.c ./drivers/block/ide-probe.c
--- /home/jskov/kernel/dist/linux-2.1.101/drivers/block/ide-probe.c	Sun May 17 14:35:11 1998
+++ ./drivers/block/ide-probe.c	Sat May 23 17:47:52 1998
@@ -574,12 +568,12 @@
 	hwgroup->hwif = HWIF(hwgroup->drive);
 	restore_flags(flags);	/* all CPUs; safe now that hwif->hwgroup is set up */
 
-#ifndef __mc68000__
+#if !defined(__mc68000__) && !defined(CONFIG_APUS)
 	printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name,
 		hwif->io_ports[IDE_DATA_OFFSET], hwif->io_ports[IDE_DATA_OFFSET]+7, hwif->io_ports[IDE_CONTROL_OFFSET], hwif->irq);
 #else
 	printk("%s at %p on irq 0x%08x", hwif->name, hwif->io_ports[IDE_DATA_OFFSET], hwif->irq);
-#endif /* __mc68000__ */
+#endif /* __mc68000__ && CONFIG_APUS */
 	if (match)
 		printk(" (%sed with %s)", hwif->sharing_irq ? "shar" : "serializ", match->name);
 	printk("\n");
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/drivers/char/amiga_ser.c ./drivers/char/amiga_ser.c
--- /home/jskov/kernel/dist/linux-2.1.101/drivers/char/amiga_ser.c	Mon Dec 15 16:04:44 1997
+++ ./drivers/char/amiga_ser.c	Sun May 17 15:03:22 1998
@@ -339,13 +339,10 @@
     else
 	info->flags |= ASYNC_CHECK_CD;
 
-    if (baud & CBAUDEX) {
-	    baud &= ~CBAUDEX;
-	    if (baud < 1 || baud > 4)
-		    info->tty->termios->c_cflag &= ~CBAUDEX;
-	    else
-		    baud += 15;
-    }
+    if (baud & CBAUDEX)
+	baud = baud - (B57600 - B38400 - 1);
+
+
     if (baud == 15) {
 	    switch (aflags) {
 	    case ASYNC_SPD_HI:
@@ -370,7 +367,7 @@
 	if (baud > 16) baud = 16;
 	realbaud = baud_table[baud];
 	if (realbaud)
-	    div = (amiga_colorclock+realbaud/2)/realbaud-1;
+	    div = (amiga_colorclock+realbaud/2)/realbaud;
     }
 
     if (div) {
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/drivers/char/m68kserial.c ./drivers/char/m68kserial.c
--- /home/jskov/kernel/dist/linux-2.1.101/drivers/char/m68kserial.c	Sun May 17 14:35:15 1998
+++ ./drivers/char/m68kserial.c	Mon May 18 22:54:53 1998
@@ -162,7 +162,7 @@
 	"unknown", "8250", "16450", "16550", "16550A"
 };
 #define PORT_MAX (sizeof(serialtypes)/sizeof(*serialtypes))
-#ifdef __mc68000__
+#if defined(__mc68000__) || defined(CONFIG_APUS)
 static char *serialtypes68k[] = {
 	"SCC w/o DMA", "SCC w/ DMA",
 	"MFP", "MFP w/o ctrl lines",
@@ -191,7 +191,7 @@
 	if (!info->port) continue;
 	if (info->type >= 0 && info->type < PORT_MAX)
 	    name = serialtypes[info->type];
-#ifdef __mc68000__
+#if defined(__mc68000__) || defined(CONFIG_APUS)
 	else if (info->type >= 100 && info->type < 100 + M68K_PORT_MAX)
 	    name = serialtypes68k[info->type - 100];
 #endif
@@ -1531,7 +1521,7 @@
 
 	save_flags(flags);
 	cli();
-#ifndef __mc68000__
+#if !defined(__mc68000__) && !defined(CONFIG_APUS)
 	for (i = 0; i < NR_PORTS; i++) {
 		if (rs_table[i].port == req->port)
 			break;
@@ -1566,7 +1556,7 @@
 		       "device already open\n", i, req->port, req->irq);
 		return -EBUSY;
 	}
-#ifndef __mc68000__
+#if !defined(__mc68000__) && !defined(CONFIG_APUS)
 	info->irq = req->irq;
 	info->port = req->port;
 	autoconfig(info);
@@ -1584,7 +1574,7 @@
 #endif
 	if (info->type >= 0 && info->type < PORT_MAX)
 	    printk( "%s\n", serialtypes[info->type] );
-#ifdef __mc68000__
+#if defined(__mc68000__) || defined(CONFIG_APUS)
 	else if (info->type >= 100 && info->type < 100 + M68K_PORT_MAX)
 	    printk( "%s\n", serialtypes68k[info->type - 100] );
 #endif
@@ -1604,7 +1594,7 @@
 	if (info->tty)
 		tty_hangup(info->tty);
 	info->type = PORT_UNKNOWN;
-#ifdef __mc68000__
+#if defined(__mc68000__) || defined(CONFIG_APUS)
 	info->port = 0;
 #endif
 	printk(KERN_INFO "tty%02d unloaded\n", info->line);
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/drivers/scsi/fastlane.c ./drivers/scsi/fastlane.c
--- /home/jskov/kernel/dist/linux-2.1.101/drivers/scsi/fastlane.c	Sun Dec 14 21:36:58 1997
+++ ./drivers/scsi/fastlane.c	Sat May 23 19:11:48 1998
@@ -289,7 +289,9 @@
 		(struct fastlane_dma_registers *) (esp->dregs);
 
 	dregs->ctrl_reg = ctrl_data & ~(FASTLANE_DMA_EDI|FASTLANE_DMA_ESI);
+#ifdef __mc68000__
 	nop();
+#endif
 	dregs->ctrl_reg = ctrl_data;
 }
 
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/drivers/video/amifb.c ./drivers/video/amifb.c
--- /home/jskov/kernel/dist/linux-2.1.101/drivers/video/amifb.c	Sun May 17 14:35:28 1998
+++ ./drivers/video/amifb.c	Sun May 24 19:21:20 1998
@@ -579,8 +580,14 @@
 #define modx(x,v)	((v) & ((x)-1))
 
 /* if x1 is not a constant, this macro won't make real sense :-) */
+#ifdef __mc68000__
 #define DIVUL(x1, x2) ({int res; asm("divul %1,%2,%3": "=d" (res): \
 	"d" (x2), "d" ((long)((x1)/0x100000000ULL)), "0" ((long)(x1))); res;})
+#else
+/* We know a bit about the numbers, so we can do it this way */
+#define DIVUL(x1, x2) ((((long)((unsigned long long)x1 >> 8) / x2) << 8) + \
+	((((long)((unsigned long long)x1 >> 8) % x2) << 8) / x2))
+#endif
 
 #define min(a, b)	((a) < (b) ? (a) : (b))
 #define max(a, b)	((a) > (b) ? (a) : (b))
@@ -1803,9 +1810,13 @@
 	 * Calculate the Pixel Clock Values for this Machine
 	 */
 
-	pixclock[TAG_SHRES] = DIVUL(25E9, amiga_eclock);	/* SHRES:  35 ns / 28 MHz */
-	pixclock[TAG_HIRES] = DIVUL(50E9, amiga_eclock);	/* HIRES:  70 ns / 14 MHz */
-	pixclock[TAG_LORES] = DIVUL(100E9, amiga_eclock); 	/* LORES: 140 ns /  7 MHz */
+	{
+	u_long tmp = DIVUL(200E9, amiga_eclock);
+
+	pixclock[TAG_SHRES] = (tmp + 4) / 8;	/* SHRES:  35 ns / 28 MHz */
+	pixclock[TAG_HIRES] = (tmp + 2) / 4;	/* HIRES:  70 ns / 14 MHz */
+	pixclock[TAG_LORES] = (tmp + 1) / 2;	/* LORES: 140 ns /  7 MHz */
+	}
 
 	/*
 	 * Replace the Tag Values with the Real Pixel Clock Values
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/drivers/video/fbcon.c ./drivers/video/fbcon.c
--- /home/jskov/kernel/dist/linux-2.1.101/drivers/video/fbcon.c	Sun May 17 14:35:28 1998
+++ ./drivers/video/fbcon.c	Sat May 23 17:48:11 1998
@@ -83,7 +83,7 @@
 #ifdef CONFIG_MAC
 #include <asm/macints.h>
 #endif
-#ifdef __mc68000__
+#if defined(__mc68000__) || defined(CONFIG_APUS)
 #include <asm/machdep.h>
 #include <asm/setup.h>
 #endif
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/drivers/video/fonts.c ./drivers/video/fonts.c
--- /home/jskov/kernel/dist/linux-2.1.101/drivers/video/fonts.c	Mon Mar  2 19:22:09 1998
+++ ./drivers/video/fonts.c	Sun May 17 15:03:24 1998
@@ -12,7 +12,7 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/string.h>
-#ifdef __mc68000__
+#if defined(__mc68000__) || defined(CONFIG_APUS)
 #include <asm/setup.h>
 #endif
 #include "font.h"
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/include/asm-m68k/ide.h ./include/asm-m68k/ide.h
--- /home/jskov/kernel/dist/linux-2.1.101/include/asm-m68k/ide.h	Sun May 17 14:35:33 1998
+++ ./include/asm-m68k/ide.h	Sun May 17 20:52:07 1998
@@ -52,6 +52,7 @@
 	return 0;
 }
 
+#ifndef CONFIG_APUS
 /*
  *  Can we do this in a generic manner??
  */
@@ -59,6 +60,7 @@
 {
     printk("ide_init_hwif_ports: must not be called\n");
 }
+#endif
 
 typedef union {
 	unsigned all			: 8;	/* all of the bits together */
@@ -114,6 +116,7 @@
 #undef HD_DATA
 #define HD_DATA NULL
 
+#ifndef CONFIG_APUS
 #define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
 #define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
 
@@ -186,6 +189,7 @@
 		: "a" (_port), "0" (_buf),		\
 		  "d" ((_nr >> 4) - 1));		\
 })
+#endif /* !CONFIG_APUS */
 
 #ifdef CONFIG_ATARI
 #define insl_swapw(data_reg, buffer, wcount) \
diff -u --recursive -B --exclude-from=/home/jskov/lib/diff-excludes -P /home/jskov/kernel/dist/linux-2.1.101/include/asm-m68k/irq.h ./include/asm-m68k/irq.h
--- /home/jskov/kernel/dist/linux-2.1.101/include/asm-m68k/irq.h	Wed Apr 29 17:44:46 1998
+++ ./include/asm-m68k/irq.h	Sun May 17 15:03:24 1998
@@ -67,8 +67,11 @@
  *                                                      01/11/97 - Jes
  */
 
+#ifndef CONFIG_APUS
+/* Allow this file to be included from asm-ppc/irc.h without conflicts. */
 extern void (*enable_irq)(unsigned int);
 extern void (*disable_irq)(unsigned int);
+#endif
 
 extern int sys_request_irq(unsigned int, 
 	void (*)(int, void *, struct pt_regs *), 


