NetBSD Problem Report #48600

From www@NetBSD.org  Sun Feb 16 19:33:02 2014
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 0A9ADA5673
	for <gnats-bugs@gnats.NetBSD.org>; Sun, 16 Feb 2014 19:33:02 +0000 (UTC)
Message-Id: <20140216193253.D6488A64B7@mollari.NetBSD.org>
Date: Sun, 16 Feb 2014 19:32:53 +0000 (UTC)
From: scole_mail@gmx.com
Reply-To: scole_mail@gmx.com
To: gnats-bugs@NetBSD.org
Subject: Add support for powermac 7200/PPC 601
X-Send-Pr-Version: www-1.0

>Number:         48600
>Category:       port-macppc
>Synopsis:       Add support for powermac 7200/PPC 601
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    port-macppc-maintainer
>State:          closed
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Feb 16 19:35:00 +0000 2014
>Closed-Date:    Wed Sep 21 19:44:07 +0000 2016
>Last-Modified:  Wed Sep 21 19:44:07 +0000 2016
>Originator:     scole_mail
>Release:        current
>Organization:
>Environment:
NetBSD pmac 6.99.31 NetBSD 6.99.31 (GENERIC-$Revision: 1.311 $) #41: Sat Feb 15 19:12:03 MST 2014
>Description:
I've attached the patches used to get my powermac 7200/90Mhz ppc601 to
boot multiuser, for serial console only.  The machine I have doesn't
have working floppy/cdrom/hard-disk, so I only tested with nfs root.

These changes seem pretty stable; I'm able to ssh and compile pkgsrc
packages with crashing or noticable issues.

The main issues I had related to the 601
 1) segment registers, especially reg 0xf - trying to set this to certain values or clearing seemed to wedge machine.  So I did't modify until in pmap.c and only when it seemed required

 2) Use rtc realtime register instead of timebase register, which 601 doesn't have.  It's possible I may have missed some asm calls to mftb/mttb

 3) alignment exceptions - the 601 will throw alignment exceptions if operands cross page boundaries.   I updated trap.c to handle that, and  changed memcpy.S to always use byte-copy (not word-copy) when in kernel.  There may be a more optimal way to handle. Also, I'm not that familiar with other powerpc's, so my handler changes may need tweaking for other cpus

  4) use CPUFLAGS+= -mcpu=601.  Also, the kernel apparently has to be  < 4M to netboot

  5) /platinum video - video console is not working. I'm not that familar with this area, but I'll be glad to test any changes

Here is list of files I changed, those with (*) are new:
 src/common/lib/libc/arch/powerpc/string/memcpy.S
 src/sys/arch/macppc/conf/GENERIC_601*
 src/sys/arch/macppc/conf/std.macppc.601*
 src/sys/arch/macppc/stand/ofwboot/Locore.c
 src/sys/arch/powerpc/include/cpu.h
 src/sys/arch/powerpc/include/trap.h
 src/sys/arch/powerpc/oea/oea_machdep.c
 src/sys/arch/powerpc/oea/ofwoea_machdep.c
 src/sys/arch/powerpc/oea/pmap.c
 src/sys/arch/powerpc/powerpc/clock.c
 src/sys/arch/powerpc/powerpc/trap.c
 src/sys/arch/powerpc/powerpc/fixup.c

These 2 mail threads were useful in getting started...
 http://mail-index.netbsd.org/port-macppc/2005/04/22/0004.html
 http://mail-index.netbsd.org/port-macppc/2008/09/28/msg000422.html
-----------------------------------------------------------------------
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 6.99.31 (GENERIC-$Revision: 1.311 $) #41: Sat Feb 15 19:12:03 MST 2014
        scole@dstar:/home/scole/nbsd/src/sys/arch/macppc/compile/obj/GENERIC_601
total memory = 256 MB
avail memory = 244 MB
timecounter: Timecounters tick every 10.000 msec
found Grand Central PIC at f3000000
bootpath: enet/netbsd
mainbus0 (root)
cpu0 at mainbus0: 601 (Revision 2), ID 0 (primary)
cpu0: HID0 0x818100a0<CE,BA,BD,ES,EIU,DRF>, powersave: -1
memory0 at mainbus0
bandit0 at mainbus0
pci0 at bandit0 bus 0
pci0: i/o space, memory space enabled
pchb0 at pci0 dev 11 function 0
WARNING: module error: vfs load failed for `pciverbose', error 45
WARNING: module error: vfs load failed for `pciverbose', error 45
pchb0: vendor 0x106b product 0x0001 (rev. 0x03)
obio0 at pci0 dev 16 function 0: addr 0xf3000000
esp0 at obio0 offset 0x10000 irq 12: NCR53C94, 25MHz, SCSI ID 7
scsibus0 at esp0: 8 targets, 8 luns per target
mc0 at obio0 offset 0x11000: irq 14,2,3: address 00:a0:40:02:bb:b5
zsc0 at obio0 irq 15,16
zstty0 at zsc0 channel 0 (console i/o)
zstty1 at zsc0 channel 1
awacs at obio0 offset 0x14000 not configured
swim3 at obio0 offset 0x15000 not configured
cuda0 at obio0 offset 0x16000 irq 18
nadb0 at cuda0: Apple Desktop Bus
iic0 at cuda0: I2C bus
nvram0 at obio0 offset 0x1d000
vmmask 7e000000 schedmask 7e000000 highmask 7e000000
timecounter: Timecounter "clockinterrupt" frequency 100 Hz quality 0
timecounter: Timecounter "rtc" frequency 1000000000 Hz quality 100
scsibus0: waiting 2 seconds for devices to settle...
adbkbd0 at nadb0 addr 2: extended keyboard
wskbd0 at adbkbd0 mux 1
cd0 at scsibus0 target 3 lun 0: <SONY, CD-ROM CDU-8005, 1.0j> cdrom removable
cd0: sync (200.00ns offset 15), 8-bit (5.000MB/s) transfers
boot device: mc0
root on mc0
mountroot: trying nfs...
nfs_boot: trying DHCP/BOOTP
nfs_boot: DHCP next-server: 192.168.0.3
nfs_boot: my_name=macppc
nfs_boot: my_addr=192.168.0.99
nfs_boot: my_mask=255.255.255.0
nfs_boot: gateway=192.168.0.1
root on 192.168.0.3:/export/client/root
root time: 0x53000def
root file system type: nfs
init: copying out path `/sbin/init' 11
192.168.0.3:/export/client/root: inaccurate wcc data (ctime) detected, disabling wcc (ctime 1392563376.000000000)
short packet len=2
short packet len=2
short packet len=2
Kernel RNG "sysctl" runs test FAILURE: too many runs of 1 0s (2712 > 2685)
cprng sysctl: failed statistical RNG test

NetBSD/macppc (pmac) (ttyZ0)

login: root
Password:
Feb 16 11:37:59 pmac login: ROOT LOGIN (root) on tty ttyZ0
Last login: Sun Feb 16 11:34:22 2014 on ttyZ0
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 6.99.31 (GENERIC-$Revision: 1.311 $) #41: Sat Feb 15 19:12:03 MST 2014

Welcome to NetBSD!

This system is running a development snapshot of the NetBSD operating system,
also known as NetBSD-current.  It is very possible that it has serious bugs,
regressions, broken features or other problems.  Please bear this in mind
and use the system with care.

You are encouraged to test this version as thoroughly as possible.  Should you
encounter any problem, please report it back to the development team using the
send-pr(1) utility (requires a working MTA).  If yours is not properly set up,
use the web interface at: http://www.NetBSD.org/support/send-pr.html

Thank you for helping us test and improve NetBSD.

You have new mail.
Terminal type is vt100.                                                 
We recommend that you create a non-root account and use su(1) for root access.
pmac# uname -a
NetBSD pmac 6.99.31 NetBSD 6.99.31 (GENERIC-$Revision: 1.311 $) #41: Sat Feb 15 19:12:03 MST 2014
===================================================================
===================================================================
===================================================================
===================================================================
===================================================================


Index: common/lib/libc/arch/powerpc/string/memcpy.S
===================================================================
RCS file: /cvsroot/src/common/lib/libc/arch/powerpc/string/memcpy.S,v
retrieving revision 1.3
diff -b -u -r1.3 memcpy.S
--- common/lib/libc/arch/powerpc/string/memcpy.S	15 Jan 2011 07:31:12 -0000	1.3
+++ common/lib/libc/arch/powerpc/string/memcpy.S	16 Feb 2014 18:18:48 -0000
@@ -63,6 +63,32 @@
 	cmpwi	%r5,0
 	beqlr-

+#if defined(_KERNEL)  /* XXX - " && defined(__ppc601__)" ? */
+	/*
+	* 601 will generate alignment exceptions if operand crosses
+	 * 4k page boundary, so do byte copy when exception handler
+	 * not available.  Maybe want to have a different memcpy for 601
+	 * that checks for page boundaries/word alignment...
+	 */
+	mfspr   %r6, 287		/* mfpvbr %r6 PVR = 287       */
+	srwi    %r6, %r6, 0x10		/* get version field from PVR */
+	cmpwi   %r6, 0x1		/* 601 CPU = 0x0001           */
+	bne     bnorm			/* skip byte-only unless 601  */
+
+bcpy:
+	mtctr   %r5			/* byte copy everything */
+	li      %r6, 0
+bloop:		
+	lbzx    %r7, %r4, %r6
+	stbx    %r7, %r3, %r6
+	addi    %r6, %r6, 1
+	bdnz    bloop
+	blr
+
+bnorm:
+
+#endif	
+
 	mr	%r8, %r3		/* Copy dst (return value)	*/

 	addi	%r4, %r4, -4		/* Prepare for main loop's auto	*/
Index: sys/arch/macppc/stand/ofwboot/Locore.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/stand/ofwboot/Locore.c,v
retrieving revision 1.24
diff -b -u -r1.24 Locore.c
--- sys/arch/macppc/stand/ofwboot/Locore.c	17 Jul 2011 20:54:43 -0000	1.24
+++ sys/arch/macppc/stand/ofwboot/Locore.c	16 Feb 2014 18:20:17 -0000
@@ -69,6 +69,12 @@
 "	mtmsr	%r0		\n"
 "	isync			\n"
 "				\n"
+"				\n" /* test for 601 */
+"       mfspr   %r0,287      	\n" /* mfpvbr %r0 PVR = 287 */
+"       srwi    %r0,%r0,0x10   	\n"
+"       cmpi    0,1,%r0,0x02  	\n" /* 601 CPU = 0x0001 */
+"       blt     1f		\n" /* skip over non-601 BAT setup */
+	/*non PPC 601 BATs*/
 "	mtibatu	0,%r0		\n"
 "	mtibatu	1,%r0		\n"
 "	mtibatu	2,%r0		\n"
@@ -84,7 +90,41 @@
 "	li	%r9,0x1ffe	\n"	/* BATU(0, BAT_BL_256M, BAT_Vs) */
 "	mtibatu	0,%r9		\n"
 "	mtdbatu	0,%r9		\n"
-"	isync			\n"
+"	b 2f			\n"
+
+	/* PPC 601 BATs*/
+"1:	mtibatu	0,%r0		\n"
+"      	mtibatu 1,%r0           \n"
+"      	mtibatu 2,%r0           \n"
+"      	mtibatu 3,%r0           \n"
+"                              	\n"
+"      	li      %r9,0x7f        \n"
+"      	mtibatl 0,%r9           \n"
+"      	li      %r9,0x1a        \n"
+"      	mtibatu 0,%r9           \n"
+"				\n"
+"      	lis %r9,0x80    	\n"
+"      	addi %r9,%r9,0x7f       \n"
+"      	mtibatl 1,%r9           \n"
+"      	lis %r9,0x80    	\n"
+"      	addi %r9,%r9,0x1a       \n"
+"      	mtibatu 1,%r9           \n"
+"				\n"
+"      	lis %r9,0x100   	\n"
+"      	addi %r9,%r9,0x7f      	\n"
+"      	mtibatl 2,%r9          	\n"
+"      	lis %r9,0x100   	\n"
+"      	addi %r9,%r9,0x1a      	\n"
+"      	mtibatu 2,%r9          	\n"
+"				\n"
+"      	lis %r9,0x180   	\n"
+"      	addi %r9,%r9,0x7f       \n"
+"      	mtibatl 3,%r9           \n"
+"     	lis %r9,0x180   	\n"
+"      	addi %r9,%r9,0x1a       \n"
+"      	mtibatu 3,%r9           \n"
+"				\n"
+"2:	isync			\n"
 "				\n"
 "	mtmsr	%r8		\n"
 "	isync			\n"
Index: sys/arch/powerpc/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/include/cpu.h,v
retrieving revision 1.98
diff -b -u -r1.98 cpu.h
--- sys/arch/powerpc/include/cpu.h	8 Nov 2013 03:59:35 -0000	1.98
+++ sys/arch/powerpc/include/cpu.h	16 Feb 2014 18:21:18 -0000
@@ -316,6 +316,26 @@
 	    : [rtcu] "=r"(rtcp[0]), [rtcl] "=r"(rtcp[1]), [tmp] "=r"(tmp)
 	    :: "cr0");
 }
+
+static __inline uint64_t
+rtc_nanosecs(void)
+{
+    /* 
+     * 601 RTC/DEC registers share clock of 7.8125 MHz, 128 ns per tick.
+     * DEC has max of 25 bits, FFFFFF => 2.14748352 seconds.
+     * RTCU is seconds, 32 bits.
+     * RTCL is nano-seconds, 23 bit counter from 0 - 999,999,872 (999,999,999 - 128 ns)
+     */
+    uint64_t cycles;
+    uint32_t tmp[2];
+
+    mfrtc(tmp);
+
+    cycles = tmp[0] * 1000000000;
+    cycles += (tmp[1] >> 7);
+
+    return cycles;
+}
 #endif /* !_MODULE */

 static __inline uint32_t
Index: sys/arch/powerpc/include/trap.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/include/trap.h,v
retrieving revision 1.12
diff -b -u -r1.12 trap.h
--- sys/arch/powerpc/include/trap.h	18 Jul 2012 16:44:52 -0000	1.12
+++ sys/arch/powerpc/include/trap.h	16 Feb 2014 18:21:38 -0000
@@ -47,7 +47,8 @@
 #define	EXC_TRC		0x0d00		/* Trace */
 #define	EXC_FPA		0x0e00		/* Floating-point Assist */

-/* The following is only available on the 601: */
+/* The following are only available on the 601: */
+#define EXC_IOC         0x0a00          /* I/O Controller Interface Exception */
 #define	EXC_RUNMODETRC	0x2000		/* Run Mode/Trace Exception */

 /* The following are only available on 7400(G4): */
@@ -112,12 +113,78 @@
  */

 #define EXC_ALI_OPCODE_INDICATOR(dsisr) ((dsisr >> 10) & 0x7f)
+
+#define EXC_ALI_LWARX_LWZ  0x00
+#define EXC_ALI_LDARX      0x01
+#define EXC_ALI_STW        0x02
+#define EXC_ALI_LHZ        0x04
+#define EXC_ALI_LHA        0x05
+#define EXC_ALI_STH        0x06
+#define EXC_ALI_LMW        0x07
+#define EXC_ALI_LFS        0x08
 #define EXC_ALI_LFD	0x09
+#define EXC_ALI_STFS       0x0a
 #define EXC_ALI_STFD	0x0b
+#define EXC_ALI_LD_LDU_LWA 0x0d
+#define EXC_ALI_STD_STDU   0x0f
+#define EXC_ALI_LWZU       0x10
+#define EXC_ALI_STWU       0x12
+#define EXC_ALI_LHZU       0x14
+#define EXC_ALI_LHAU       0x15
+#define EXC_ALI_STHU       0x16
+#define EXC_ALI_STMW       0x17
+#define EXC_ALI_LFSU       0x18
+#define EXC_ALI_LFDU       0x19
+#define EXC_ALI_STFSU      0x1a
+#define EXC_ALI_STFDU      0x1b
+#define EXC_ALI_LDX        0x20
+#define EXC_ALI_STDX       0x22
+#define EXC_ALI_LWAX       0x25
+#define EXC_ALI_LSWX       0x28
+#define EXC_ALI_LSWI       0x29
+#define EXC_ALI_STSWX      0x2a
+#define EXC_ALI_STSWI      0x2b
+#define EXC_ALI_LDUX       0x30
+#define EXC_ALI_STDUX      0x32
+#define EXC_ALI_LWAUX      0x35
+#define EXC_ALI_STWCX      0x42  /* stwcx. */
+#define EXC_ALI_STDCX      0x43  /* stdcx. */
+#define EXC_ALI_LWBRX      0x48
+#define EXC_ALI_STWBRX     0x4a
+#define EXC_ALI_LHBRX      0x4c
+#define EXC_ALI_STHBRX     0x4e
+#define EXC_ALI_ECIWX      0x54
+#define EXC_ALI_ECOWX      0x56
 #define EXC_ALI_DCBZ	0x5f
+#define EXC_ALI_LWZX       0x60
+#define EXC_ALI_STWX       0x62
+#define EXC_ALI_LHZX       0x64
+#define EXC_ALI_LHAX       0x65
+#define EXC_ALI_STHX       0x66
+#define EXC_ALI_LSFX       0x68
+#define EXC_ALI_LDFX       0x69
+#define EXC_ALI_STFSX      0x6a
+#define EXC_ALI_STFDX      0x6b
+#define EXC_ALI_STFIWX     0x6f
+#define EXC_ALI_LWZUX      0x70
+#define EXC_ALI_STWUX      0x72
+#define EXC_ALI_LHZUX      0x74
+#define EXC_ALI_LHAUX      0x75
+#define EXC_ALI_STHUX      0x76
+#define EXC_ALI_LFSUX      0x78
+#define EXC_ALI_LFDUX      0x79
+#define EXC_ALI_STFSUX     0x7a
+#define EXC_ALI_STFDUX     0x7b

 /* Macros to extract register information */
 #define EXC_ALI_RST(dsisr) ((dsisr >> 5) & 0x1f)   /* source or target */
 #define EXC_ALI_RA(dsisr) (dsisr & 0x1f)

+/* Helper defines to classify EXC_ALI_ */
+#define DSI_OP_ZERO      0x0001
+#define DSI_OP_UPDATE    0x0002
+#define DSI_OP_INDEXED   0x0004
+#define DSI_OP_ALGEBRAIC 0x0008
+#define DSI_OP_REVERSED  0x0010
+
 #endif	/* _POWERPC_TRAP_H_ */
Index: sys/arch/powerpc/oea/oea_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/oea/oea_machdep.c,v
retrieving revision 1.68
diff -b -u -r1.68 oea_machdep.c
--- sys/arch/powerpc/oea/oea_machdep.c	3 Nov 2013 22:27:27 -0000	1.68
+++ sys/arch/powerpc/oea/oea_machdep.c	16 Feb 2014 18:22:05 -0000
@@ -496,9 +496,16 @@
 	 * in pmap_bootstrap().
 	 */
 	iosrtable[i] = SR601(SR601_Ks, SR601_BUID_MEMFORCED, 0, i);
+
+	/*
+	 * XXX Setting segment register 0xf on my powermac 7200
+	 * wedges machine so set later in pmap.c
+	 */
+	/*
 	__asm volatile ("mtsrin %0,%1"
 	    ::	"r"(iosrtable[i]),
 		"r"(pa));
+	*/
 }
 #endif /* PPC_OEA601 */

Index: sys/arch/powerpc/oea/ofwoea_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/oea/ofwoea_machdep.c,v
retrieving revision 1.35
diff -b -u -r1.35 ofwoea_machdep.c
--- sys/arch/powerpc/oea/ofwoea_machdep.c	3 Nov 2013 22:27:27 -0000	1.35
+++ sys/arch/powerpc/oea/ofwoea_machdep.c	16 Feb 2014 18:22:26 -0000
@@ -63,6 +63,7 @@
 #include <powerpc/oea/bat.h>
 #include <powerpc/oea/ofw_rasconsvar.h>
 #include <powerpc/oea/cpufeat.h>
+#include <powerpc/include/oea/spr.h>
 #include <powerpc/ofw_cons.h>
 #include <powerpc/spr.h>
 #include <powerpc/pic/picvar.h>
@@ -120,6 +121,11 @@
 #if NKSYMS || defined(DDB) || defined(MODULAR)
 void *startsym, *endsym;
 #endif
+
+#if PPC_OEA601
+#define TIMEBASE_FREQ (1000000000)  /* RTC register */
+#endif
+
 #ifdef TIMEBASE_FREQ
 u_int timebase_freq = TIMEBASE_FREQ;
 #else
@@ -334,7 +340,14 @@
 	ns_per_tick = 1000000000 / ticks_per_sec;
 	ticks_per_intr = ticks_per_sec / hz;
 	cpu_timebase = ticks_per_sec;
+
+#ifdef PPC_OEA601
+	if ((mfpvr() >> 16) == MPC601)
+	    curcpu()->ci_lasttb = rtc_nanosecs();
+	else
+#endif
 	curcpu()->ci_lasttb = mftbl();
+
 	mtspr(SPR_DEC, ticks_per_intr);
 	mtmsr(msr);
 }
@@ -457,6 +470,24 @@
 	/*
 	 * cover PCI and register space but not the firmware ROM
 	 */
+#ifdef PPC_OEA601
+
+        /*
+	 * use segment registers for the 601
+	 */
+	if ((mfpvr() >> 16 ) == MPC601)
+	    oea_batinit(
+		0x80000000, BAT_BL_256M,
+		0x90000000, BAT_BL_256M,
+		0xa0000000, BAT_BL_256M,
+		0xb0000000, BAT_BL_256M,
+		0xf0000000, BAT_BL_256M,
+		0);
+	else
+#endif
+	/*
+	 * map to bats
+	 */
 	oea_batinit(0x80000000, BAT_BL_1G,
 		    0xf0000000, BAT_BL_128M,
 		    0xf8000000, BAT_BL_64M,
Index: sys/arch/powerpc/oea/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/oea/pmap.c,v
retrieving revision 1.90
diff -b -u -r1.90 pmap.c
--- sys/arch/powerpc/oea/pmap.c	3 Nov 2013 22:15:57 -0000	1.90
+++ sys/arch/powerpc/oea/pmap.c	16 Feb 2014 18:22:56 -0000
@@ -3403,6 +3403,11 @@
 /* PMAP_OEA64_BRIDGE does support these instructions */
 #if defined (PMAP_OEA) || defined (PMAP_OEA64_BRIDGE)
 	for (i = 0; i < 16; i++) {
+#if defined(PPC_OEA601)
+	    /* XXX wedges for segment register 0xf , so set later */
+	    if ((iosrtable[i] & SR601_T) && ((MFPVR() >> 16) == MPC601))
+		    continue;
+#endif
  		pmap_kernel()->pm_sr[i] = KERNELN_SEGMENT(i)|SR_PRKEY;
 		__asm volatile ("mtsrin %0,%1"
  			      :: "r"(KERNELN_SEGMENT(i)|SR_PRKEY), "r"(i << ADDR_SR_SHFT));
@@ -3530,4 +3535,9 @@
  			      :: "r"(sr), "r"(kernelstart));
 	}
 #endif
+
+#if defined(PMAPDEBUG)
+	if ( pmapdebug )
+	    pmap_print_mmuregs();
+#endif
 }
Index: sys/arch/powerpc/powerpc/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/clock.c,v
retrieving revision 1.13
diff -b -u -r1.13 clock.c
--- sys/arch/powerpc/powerpc/clock.c	25 Apr 2013 00:11:35 -0000	1.13
+++ sys/arch/powerpc/powerpc/clock.c	16 Feb 2014 18:23:19 -0000
@@ -68,7 +68,11 @@
 	0,			/* no poll_pps */
 	0x7fffffff,		/* counter_mask */
 	0,			/* frequency */
+#if PPC_OEA601
+	"rtc",			/* name */
+#else
 	"mftb",			/* name */
+#endif
 	100,			/* quality */
 	NULL,			/* tc_priv */
 	NULL			/* tc_next */
@@ -88,8 +92,7 @@
 	cpu_timebase = ticks_per_sec;
 #ifdef PPC_OEA601
 	if ((mfpvr() >> 16) == MPC601)
-		__asm volatile 
-		    ("mfspr %0,%1" : "=r"(ci->ci_lasttb) : "n"(SPR_RTCL_R));
+		ci->ci_lasttb = rtc_nanosecs();
 	else
 #endif
 		__asm volatile ("mftb %0" : "=r"(ci->ci_lasttb));
@@ -154,8 +157,7 @@
 		 */
 #ifdef PPC_OEA601
 		if ((mfpvr() >> 16) == MPC601)
-			__asm volatile 
-			    ("mfspr %0,%1" : "=r"(tb) : "n"(SPR_RTCL_R));
+			tb = rtc_nanosecs();
 		else
 #endif
 			__asm volatile ("mftb %0" : "=r"(tb));
@@ -241,7 +243,7 @@
 		      : "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE));
 #ifdef PPC_OEA601
 	if ((mfpvr() >> 16) == MPC601)
-		__asm volatile ("mfspr %0,%1" : "=r"(tb) : "n"(SPR_RTCL_R));
+		tb = rtc_nanosecs();
 	else
 #endif
 		__asm volatile ("mftb %0" : "=r"(tb));
Index: sys/arch/powerpc/powerpc/trap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/trap.c,v
retrieving revision 1.148
diff -b -u -r1.148 trap.c
--- sys/arch/powerpc/powerpc/trap.c	2 Aug 2012 14:06:34 -0000	1.148
+++ sys/arch/powerpc/powerpc/trap.c	16 Feb 2014 18:23:34 -0000
@@ -77,6 +77,13 @@
 int badaddr(void *, size_t);
 int badaddr_read(void *, size_t, int *);

+struct dsi_info {
+    uint16_t indicator;
+    uint16_t flags;
+};
+
+static struct dsi_info* get_dsi_info(register_t);
+
 void
 trap(struct trapframe *tf)
 {
@@ -695,9 +702,12 @@
 static int
 fix_unaligned(struct lwp *l, struct trapframe *tf)
 {
-	int indicator = EXC_ALI_OPCODE_INDICATOR(tf->tf_dsisr);
+	struct dsi_info* dsi = get_dsi_info(tf->tf_dsisr);
+
+	if ( !dsi )
+	    return -1;

-	switch (indicator) {
+	switch (dsi->indicator) {
 	case EXC_ALI_DCBZ:
 		{
 			/*
@@ -716,13 +726,18 @@
 				return -1;
 			return 0;
 		}
+		break;

 	case EXC_ALI_LFD:
-	case EXC_ALI_STFD:
+	case EXC_ALI_LFDU:
+	case EXC_ALI_LDFX:
+	case EXC_ALI_LFDUX:
 		{
 			struct pcb * const pcb = lwp_getpcb(l);
 			const int reg = EXC_ALI_RST(tf->tf_dsisr);
+			const int a_reg = EXC_ALI_RA(tf->tf_dsisr);
 			double * const fpreg = &pcb->pcb_fpu.fpreg[reg];
+			register_t* a_reg_addr = &tf->tf_fixreg[a_reg];

 			/*
 			 * Juggle the FPU to ensure that we've initialized
@@ -737,19 +752,260 @@
 			} else {
 				fpu_save();
 			}
-			if (indicator == EXC_ALI_LFD) {
+
 				if (copyin((void *)tf->tf_dar, fpreg,
 				    sizeof(double)) != 0)
 					return -1;
+
+			if (dsi->flags & DSI_OP_INDEXED) {
+			    /* do nothing */
+			}
+
+			if (dsi->flags & DSI_OP_UPDATE) {
+			    /* this is valid for 601, but to simplify logic don't pass for any */
+			    if (a_reg == 0)
+				return -1;
+			    else
+				*a_reg_addr = tf->tf_dar;
+			}
+
+			fpu_load();
+			return 0;
+		}
+		break;
+
+	case EXC_ALI_STFD:
+	case EXC_ALI_STFDU:
+	case EXC_ALI_STFDX:
+	case EXC_ALI_STFDUX:
+		{
+			struct pcb * const pcb = lwp_getpcb(l);
+			const int reg = EXC_ALI_RST(tf->tf_dsisr);
+			const int a_reg = EXC_ALI_RA(tf->tf_dsisr);
+			double * const fpreg = &pcb->pcb_fpu.fpreg[reg];
+			register_t* a_reg_addr = &tf->tf_fixreg[a_reg];
+
+			/*
+			 * Juggle the FPU to ensure that we've initialized
+			 * the FPRs, and that their current state is in
+			 * the PCB.
+			 */
+
+			KASSERT(l == curlwp);
+			if (!fpu_used_p(l)) {
+				memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu));
+				fpu_mark_used(l);
 			} else {
+				fpu_save();
+			}
+
 				if (copyout(fpreg, (void *)tf->tf_dar,
 				    sizeof(double)) != 0)
 					return -1;
+
+			if (dsi->flags & DSI_OP_INDEXED) {
+			    /* do nothing */
 			}
+
+			if (dsi->flags & DSI_OP_UPDATE) {
+			    /* this is valid for 601, but to simplify logic don't pass for any */
+			    if (a_reg == 0)
+				return -1;
+			    else
+				*a_reg_addr = tf->tf_dar;
+			}
+
 			fpu_load();
 			return 0;
 		}
 		break;
+
+	case EXC_ALI_LHZ:
+	case EXC_ALI_LHZU:
+	case EXC_ALI_LHZX:
+	case EXC_ALI_LHZUX:
+	case EXC_ALI_LHA:
+	case EXC_ALI_LHAU:
+	case EXC_ALI_LHAX:
+	case EXC_ALI_LHAUX:
+	case EXC_ALI_LHBRX:
+		{
+		    const register_t ea_addr = tf->tf_dar;
+		    const unsigned int t_reg = EXC_ALI_RST(tf->tf_dsisr);
+		    const unsigned int a_reg = EXC_ALI_RA(tf->tf_dsisr);
+		    register_t* t_reg_addr = &tf->tf_fixreg[t_reg];
+		    register_t* a_reg_addr = &tf->tf_fixreg[a_reg];
+
+		    /* load into lower 2 bytes of reg */
+		    if (copyin((void *)ea_addr,
+			       t_reg_addr+2,
+			       sizeof(uint16_t)) != 0)
+			return -1;
+
+		    if (dsi->flags & DSI_OP_UPDATE) {
+			/* this is valid for 601, but to simplify logic don't pass for any */
+			if (a_reg == 0)
+			    return -1;
+			else
+			    *a_reg_addr = ea_addr;
+		    }
+
+		    if (dsi->flags & DSI_OP_INDEXED) {
+			/* do nothing , indexed address already in ea */
+		    }
+
+		    if (dsi->flags & DSI_OP_ZERO) {
+			/* clear upper 2 bytes */
+			*t_reg_addr &= 0x0000ffff;
+		    } else if (dsi->flags & DSI_OP_ALGEBRAIC) {
+			/* sign extend upper 2 bytes */
+			if (*t_reg_addr & 0x00008000)
+			    *t_reg_addr |= 0xffff0000;
+			else
+			    *t_reg_addr &= 0x0000ffff;
+		    }
+
+		    if (dsi->flags & DSI_OP_REVERSED) {
+			/* reverse lower 2 bytes */
+			uint32_t temp = *t_reg_addr;
+
+			*t_reg_addr = ((temp & 0x000000ff) << 8 ) |
+			              ((temp & 0x0000ff00) >> 8 );
+		    }
+		    return 0;
+		}
+		break;
+
+	case EXC_ALI_STH:
+	case EXC_ALI_STHU:
+	case EXC_ALI_STHX:
+	case EXC_ALI_STHUX:
+	case EXC_ALI_STHBRX:
+		{
+		    const register_t ea_addr = tf->tf_dar;
+		    const unsigned int s_reg = EXC_ALI_RST(tf->tf_dsisr);
+		    const unsigned int a_reg = EXC_ALI_RA(tf->tf_dsisr);
+		    register_t* s_reg_addr = &tf->tf_fixreg[s_reg];
+		    register_t* a_reg_addr = &tf->tf_fixreg[a_reg];
+
+		    /* byte-reversed write out of lower 2 bytes */
+		    if (dsi->flags & DSI_OP_REVERSED) {
+			uint16_t tmp = *s_reg_addr & 0xffff;
+			tmp = bswap16(tmp);
+
+			if (copyout(&tmp,
+				    (void *)ea_addr,
+				    sizeof(uint16_t)) != 0)
+			    return -1;
+		    }
+		    /* write out lower 2 bytes */
+		    else if (copyout(s_reg_addr+2,
+				     (void *)ea_addr,
+				     sizeof(uint16_t)) != 0) {
+			return -1;
+		    }
+
+		    if (dsi->flags & DSI_OP_INDEXED) {
+			/* do nothing, indexed address already in ea */
+		    }
+
+		    if (dsi->flags & DSI_OP_UPDATE) {
+			/* this is valid for 601, but to simplify logic don't pass for any */
+			if (a_reg == 0)
+			    return -1;
+			else
+			    *a_reg_addr = ea_addr;
+		    }
+
+		    return 0;
+		}
+		break;
+
+	case EXC_ALI_LWARX_LWZ:
+	case EXC_ALI_LWZU:
+	case EXC_ALI_LWZX:
+	case EXC_ALI_LWZUX:
+	case EXC_ALI_LWBRX:
+		{
+		    const register_t ea_addr = tf->tf_dar;
+		    const unsigned int t_reg = EXC_ALI_RST(tf->tf_dsisr);
+		    const unsigned int a_reg = EXC_ALI_RA(tf->tf_dsisr);
+		    register_t* t_reg_addr = &tf->tf_fixreg[t_reg];
+		    register_t* a_reg_addr = &tf->tf_fixreg[a_reg];
+
+		    if (copyin((void *)ea_addr,
+			       t_reg_addr,
+			       sizeof(uint32_t)) != 0)
+			return -1;
+
+		    if (dsi->flags & DSI_OP_UPDATE) {
+			/* this is valid for 601, but to simplify logic don't pass for any */
+			if (a_reg == 0)
+			    return -1;
+			else
+			    *a_reg_addr = ea_addr;
+		    }
+
+		    if (dsi->flags & DSI_OP_INDEXED) {
+			/* do nothing , indexed address already in ea */
+		    }
+
+		    if (dsi->flags & DSI_OP_ZERO) {
+			/* XXX - 64bit clear upper word */
+		    }
+
+		    if (dsi->flags & DSI_OP_REVERSED) {
+			/* reverse  bytes */
+			register_t temp = bswap32(*t_reg_addr);
+			*t_reg_addr = temp;
+		    }
+
+		    return 0;
+		}
+		break;
+
+	case EXC_ALI_STW:
+	case EXC_ALI_STWU:
+	case EXC_ALI_STWX:
+	case EXC_ALI_STWUX:
+	case EXC_ALI_STWBRX:
+		{
+		    const register_t ea_addr = tf->tf_dar;
+		    const unsigned int s_reg = EXC_ALI_RST(tf->tf_dsisr);
+		    const unsigned int a_reg = EXC_ALI_RA(tf->tf_dsisr);
+		    register_t* s_reg_addr = &tf->tf_fixreg[s_reg];
+		    register_t* a_reg_addr = &tf->tf_fixreg[a_reg];
+
+		    if (dsi->flags & DSI_OP_REVERSED) {
+			/* byte-reversed write out */
+			register_t temp = bswap32(*s_reg_addr);
+
+			if (copyout(&temp,
+				    (void *)ea_addr,
+				    sizeof(uint32_t)) != 0)
+			    return -1;
+		    }
+		    /* write out word */
+		    else if (copyout(s_reg_addr,
+				     (void *)ea_addr,
+				     sizeof(uint32_t)) != 0)
+			return -1;
+
+		    if (dsi->flags & DSI_OP_INDEXED) {
+			/* do nothing, indexed address already in ea */
+		    }
+
+		    if (dsi->flags & DSI_OP_UPDATE) {
+			/* this is valid for 601, but to simplify logic don't pass for any */
+			if (a_reg == 0)
+			    return -1;
+			else
+			    *a_reg_addr = ea_addr;
+		    }
+
+		    return 0;
+		}
+		break;
 	}

 	return -1;
@@ -892,3 +1148,123 @@
 	curpcb->pcb_onfault = 0;
 	return rv;
 }
+
+struct dsi_info*
+get_dsi_info(register_t dsisr)
+{
+    static struct dsi_info dsi[] = 
+	{
+	    /* data cache block zero */
+	    {EXC_ALI_DCBZ, 0},
+
+	    /* load halfwords */
+	    {EXC_ALI_LHZ,   DSI_OP_ZERO},
+	    {EXC_ALI_LHZU,  DSI_OP_ZERO|DSI_OP_UPDATE},
+	    {EXC_ALI_LHZX,  DSI_OP_ZERO|DSI_OP_INDEXED},
+	    {EXC_ALI_LHZUX, DSI_OP_ZERO|DSI_OP_UPDATE|DSI_OP_INDEXED},
+	    {EXC_ALI_LHA,   DSI_OP_ALGEBRAIC},
+	    {EXC_ALI_LHAU,  DSI_OP_ALGEBRAIC|DSI_OP_UPDATE},
+	    {EXC_ALI_LHAX,  DSI_OP_ALGEBRAIC|DSI_OP_INDEXED},
+	    {EXC_ALI_LHAUX, DSI_OP_ALGEBRAIC|DSI_OP_UPDATE|DSI_OP_INDEXED},
+
+	    /* store halfwords */
+	    {EXC_ALI_STH,   0},
+	    {EXC_ALI_STHU,  DSI_OP_UPDATE},
+	    {EXC_ALI_STHX,  DSI_OP_INDEXED},
+	    {EXC_ALI_STHUX, DSI_OP_UPDATE|DSI_OP_INDEXED},
+
+	    /* load words */
+	    {EXC_ALI_LWARX_LWZ, DSI_OP_ZERO},
+	    {EXC_ALI_LWZU,      DSI_OP_ZERO|DSI_OP_UPDATE},
+	    {EXC_ALI_LWZX,      DSI_OP_ZERO|DSI_OP_INDEXED},
+	    {EXC_ALI_LWZUX,     DSI_OP_ZERO|DSI_OP_UPDATE|DSI_OP_INDEXED},
+
+	    /* store words */
+	    {EXC_ALI_STW,   0},				  
+	    {EXC_ALI_STWU,  DSI_OP_UPDATE},		  
+	    {EXC_ALI_STWX,  DSI_OP_INDEXED},		  
+	    {EXC_ALI_STWUX, DSI_OP_UPDATE|DSI_OP_INDEXED},
+
+	    /* load byte-reversed */
+	    {EXC_ALI_LHBRX, DSI_OP_REVERSED|DSI_OP_INDEXED|DSI_OP_ZERO},
+	    {EXC_ALI_LWBRX, DSI_OP_REVERSED|DSI_OP_INDEXED},
+
+	    /* store byte-reversed */
+	    {EXC_ALI_STHBRX, DSI_OP_REVERSED|DSI_OP_INDEXED},
+	    {EXC_ALI_STWBRX, DSI_OP_REVERSED|DSI_OP_INDEXED},
+
+	    /* load float double-precision */
+	    {EXC_ALI_LFD,   0},
+	    {EXC_ALI_LFDU,  DSI_OP_UPDATE},
+	    {EXC_ALI_LDFX,  DSI_OP_INDEXED},
+	    {EXC_ALI_LFDUX, DSI_OP_UPDATE|DSI_OP_INDEXED},
+
+	    /* store float double precision */
+	    {EXC_ALI_STFD,   0},
+	    {EXC_ALI_STFDU,  DSI_OP_UPDATE},
+	    {EXC_ALI_STFDX,  DSI_OP_INDEXED},
+	    {EXC_ALI_STFDUX, DSI_OP_UPDATE|DSI_OP_INDEXED},
+
+	    /* XXX - ones below here not yet implemented in fix_unaligned() */
+	    /* load float single precision */
+	    {EXC_ALI_LFS,   0},
+	    {EXC_ALI_LFSU,  DSI_OP_UPDATE},
+	    {EXC_ALI_LSFX,  DSI_OP_INDEXED},
+	    {EXC_ALI_LFSUX, DSI_OP_UPDATE|DSI_OP_INDEXED},
+
+	    /* store float single precision */
+	    {EXC_ALI_STFS,   0},
+	    {EXC_ALI_STFSU,  DSI_OP_UPDATE},
+	    {EXC_ALI_STFSX,  DSI_OP_INDEXED},
+	    {EXC_ALI_STFSUX, DSI_OP_UPDATE|DSI_OP_INDEXED},
+
+	    /* multiple */
+	    {EXC_ALI_LMW,  0},
+	    {EXC_ALI_STMW, 0},
+
+	    /* load & store string */
+	    {EXC_ALI_LSWI, 0},
+	    {EXC_ALI_LSWX, DSI_OP_INDEXED},
+	    {EXC_ALI_STSWI, 0},
+	    {EXC_ALI_STSWX, DSI_OP_INDEXED},
+
+	    /* get/send word from external */
+	    {EXC_ALI_ECIWX, DSI_OP_INDEXED},
+	    {EXC_ALI_ECOWX, DSI_OP_INDEXED},
+
+	    /* store float as integer word */
+	    {EXC_ALI_STFIWX, 0},
+
+	    /* store conditional */
+	    {EXC_ALI_LDARX, DSI_OP_INDEXED}, /* stdcx */
+	    {EXC_ALI_STDCX, DSI_OP_INDEXED},
+	    {EXC_ALI_STWCX, DSI_OP_INDEXED},  /* lwarx */
+
+#ifdef PPC_OEA64
+	    /* 64 bit, load word algebriac */ 
+	    {EXC_ALI_LWAX,  DSI_OP_ALGEBRAIC|DSI_OP_INDEXED},
+	    {EXC_ALI_LWAUX, DSI_OP_ALGEBRAIC|DSI_OP_UPDATE|DSI_OP_INDEXED},
+
+	    /* 64 bit load doubleword */
+	    {EXC_ALI_LD_LDU_LWA, 0},
+	    {EXC_ALI_LDX,        DSI_OP_INDEXED},
+	    {EXC_ALI_LDUX,       DSI_OP_UPDATE|DSI_OP_INDEXED},
+
+	    /* 64 bit store double word */
+	    {EXC_ALI_STD_STDU, 0},
+	    {EXC_ALI_STDX,     DSI_OP_INDEXED},
+	    {EXC_ALI_STDUX,    DSI_OP_UPDATE|DSI_OP_INDEXED},
+#endif
+	};
+
+    int num_elems = sizeof(dsi)/sizeof(dsi[0]);
+    int indicator = EXC_ALI_OPCODE_INDICATOR(dsisr);
+    int i;
+
+    for (i = 0 ; i < num_elems; i++) {
+	if (indicator == dsi[i].indicator){
+	    return &dsi[i];
+	}
+    }
+    return 0;
+}
Index: sys/arch/powerpc/powerpc/fixup.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/fixup.c,v
retrieving revision 1.6
diff -b -u -r1.6 fixup.c
--- sys/arch/powerpc/powerpc/fixup.c	7 Nov 2013 15:26:36 -0000	1.6
+++ sys/arch/powerpc/powerpc/fixup.c	16 Feb 2014 18:23:53 -0000
@@ -43,6 +43,8 @@

 #include <powerpc/instr.h>
 #include <powerpc/spr.h>
+#include <powerpc/include/cpu.h>
+#include <powerpc/include/oea/spr.h>

 static inline void
 fixup_jump(uint32_t *insnp, const struct powerpc_jump_fixup_info *jfi)
@@ -71,7 +73,13 @@
 	extern uint32_t __stub_start[], __stub_end[];
 #ifdef DEBUG
 	size_t fixups_done = 0;
-	uint64_t cycles = mftb();
+	uint64_t cycles = 0;
+#ifdef PPC_OEA601
+	if ((mfpvr() >> 16) == MPC601)
+	    cycles = rtc_nanosecs()/128;
+	else
+#endif
+	    cycles = mftb();
 #endif

 	if (stub_start == NULL) {
@@ -209,7 +217,14 @@
 	}

 #ifdef DEBUG
+
+#ifdef PPC_OEA601
+	if ((mfpvr() >> 16) == MPC601)
+	    cycles = rtc_nanosecs()/128 - cycles;
+	else
+#endif
 	cycles = mftb() - cycles;
+
 	printf("%s: %zu fixup%s done in %"PRIu64" cycles\n", __func__,
 	    fixups_done, fixups_done == 1 ? "" : "s",
 	    cycles);

===================================================================
New file
sys/arch/macppc/conf/std.macppc.601
===================================================================
#	$NetBSD: std.macppc,v 1.23 2008/12/11 05:42:18 alc Exp $
#
# Standard/required options for NetBSD/macppc.

machine	macppc powerpc
include		"conf/std"	# MI standard options

# standard ("mandatory") kernel options.
options 	PPC_OEA		# OEA class PowerPC chips
options         PPC_OEA601      # 601 cpu
makeoptions	PPCDIR="oea"	# Tell Makefile.powerpc what dir to use
makeoptions     PPC_ARCH_MODE="ppc32"
makeoptions	CPUFLAGS+="-mcpu=601"

# Executable support:
options 	EXEC_ELF32	# (native) ELF32 binary support
options 	EXEC_AOUT	# (native) a.out binary support (deprecated)
options 	EXEC_SCRIPT	# shell script support

options 	INTSTK=0x2000

# Atheros HAL options
include "external/isc/atheros_hal/conf/std.ath_hal"
New file, diffed between GENERIC.  Most of changes are to reduce
kernel size < 4M
GENERIC_601
======================================================================
--- sys/arch/macppc/conf/GENERIC	2013-11-09 08:45:35.000000000 -0700
+++ sys/arch/macppc/conf/GENERIC_601	2014-02-12 09:05:13.000000000 -0700
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.312 2013/10/23 09:28:57 macallan Exp $
+# $NetBSD: GENERIC,v 1.311 2013/06/30 21:38:57 rmind Exp $
 #
 # GENERIC machine description file
 # 
@@ -17,16 +17,20 @@
 # for this architecture, see the options(4) man page.  For an explanation
 # of each device driver in this file see the section 4 man page for the
 # device.
-
-include		"arch/macppc/conf/std.macppc"
+#
+# For PPC 601, need "CPUFLAGS+= -mcpu=601"
+#
+# Openfirmware 1.0.5 require a kernel < 4M for netbooting
+#
+include		"arch/macppc/conf/std.macppc.601"

 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary

-#ident 		"GENERIC-$Revision: 1.312 $"
+ident 		"GENERIC-$Revision: 1.311 $"

 maxusers	32

-options 	ALTIVEC		# Include AltiVec support
+#options 	ALTIVEC		# Include AltiVec support

 # Standard system options
 options 	INSECURE	# disable kernel security levels
@@ -39,9 +43,9 @@
 options 	SYSVSEM		# System V semaphores
 options 	SYSVSHM		# System V shared memory

-options 	MODULAR		# new style module(7) framework
+#options 	MODULAR		# new style module(7) framework

-options 	USERCONF	# userconf(4) support
+#options 	USERCONF	# userconf(4) support
 #options 	PIPE_SOCKETPAIR	# smaller, but slower pipe(2)
 options 	SYSCTL_INCLUDE_DESCR	# Include sysctl descriptions in kernel

@@ -51,95 +55,98 @@
 #options 	BUFQ_PRIOCSCAN

 # Diagnostic/debugging support options
-#options 	DIAGNOSTIC	# cheap kernel consistency checks
-#options 	DEBUG		# expensive debugging checks/support
+options 	DIAGNOSTIC	# cheap kernel consistency checks
+options 	DEBUG		# expensive debugging checks/support
 options 	ZS_CONSOLE_ABORT# allow break to get into DDB on serial
 options 	DDB		# in-kernel debugger
 #options 	DDB_ONPANIC=0	# don't go into ddb on panic.
 options 	DDB_HISTORY_SIZE=512	# enable history editing in DDB
-#options 	TRAP_PANICWAIT
+options 	TRAP_PANICWAIT
 options		DDB_COMMANDONENTER="bt"

-#makeoptions 	DEBUG="-g"	# compile full symbol table
+options 	PMAPCHECK
+options 	PMAPDEBUG
+
+makeoptions 	DEBUG="-g"	# compile full symbol table

 # Compatibility options
-options 	COMPAT_09	# NetBSD 0.9,
-options 	COMPAT_10	# NetBSD 1.0,
-options 	COMPAT_11	# NetBSD 1.1,
-options 	COMPAT_12	# NetBSD 1.2,
-options 	COMPAT_13	# NetBSD 1.3,
-options 	COMPAT_14	# NetBSD 1.4,
-options 	COMPAT_15	# NetBSD 1.5,
-options 	COMPAT_16	# NetBSD 1.6,
-options 	COMPAT_20	# NetBSD 2.0,
-options 	COMPAT_30	# NetBSD 3.0,
-options 	COMPAT_40	# NetBSD 4.0 compatibility.
-options 	COMPAT_50	# NetBSD 5.0 compatibility.
+#options 	COMPAT_09	# NetBSD 0.9,
+#options 	COMPAT_10	# NetBSD 1.0,
+#options 	COMPAT_11	# NetBSD 1.1,
+#options 	COMPAT_12	# NetBSD 1.2,
+#options 	COMPAT_13	# NetBSD 1.3,
+#options 	COMPAT_14	# NetBSD 1.4,
+#options 	COMPAT_15	# NetBSD 1.5,
+#options 	COMPAT_16	# NetBSD 1.6,
+#options 	COMPAT_20	# NetBSD 2.0,
+#options 	COMPAT_30	# NetBSD 3.0,
+#options 	COMPAT_40	# NetBSD 4.0 compatibility.
+#options 	COMPAT_50	# NetBSD 5.0 compatibility.
 options 	COMPAT_60	# NetBSD 6.0 compatibility.
 options 	COMPAT_43	# and 4.3BSD
 #options 	COMPAT_386BSD_MBRPART # recognize old partition ID
 #options 	COMPAT_LINUX	# Linux binary compatibility
 #options 	TCP_COMPAT_42	# 4.2BSD TCP/IP bug compat. Not recommended.
-options 	COMPAT_BSDPTY	# /dev/[pt]ty?? ptys.
+#options 	COMPAT_BSDPTY	# /dev/[pt]ty?? ptys.

 # Wedge support
-options         DKWEDGE_AUTODISCOVER    # Automatically add dk(4) instances
-options         DKWEDGE_METHOD_GPT      # Supports GPT partitions as wedges
+#options         DKWEDGE_AUTODISCOVER    # Automatically add dk(4) instances
+#options         DKWEDGE_METHOD_GPT      # Supports GPT partitions as wedges
 # The following two options can break /etc/fstab, so handle with care
 #options        DKWEDGE_METHOD_BSDLABEL # Support disklabel entries as wedges
 #options        DKWEDGE_METHOD_MBR      # Support MBR partitions as wedges

 # File systems
 file-system 	FFS		# UFS
-file-system 	EXT2FS		# second extended file system (linux)
-file-system 	LFS		# log-structured file system
+#file-system 	EXT2FS		# second extended file system (linux)
+#file-system 	LFS		# log-structured file system
 file-system 	MFS		# memory file system
 file-system 	NFS		# Network File System client
 file-system 	CD9660		# ISO 9660 + Rock Ridge file system
 file-system 	MSDOSFS		# MS-DOS file system
-file-system 	FDESC		# /dev/fd
-file-system 	KERNFS		# /kern
-file-system 	NULLFS		# loopback file system
-file-system 	OVERLAY		# overlay file system
-file-system	PUFFS		# Userspace file systems (e.g. ntfs-3g & sshfs)
+#file-system 	FDESC		# /dev/fd
+#file-system 	KERNFS		# /kern
+#file-system 	NULLFS		# loopback file system
+#file-system 	OVERLAY		# overlay file system
+#file-system	PUFFS		# Userspace file systems (e.g. ntfs-3g & sshfs)
 file-system 	PROCFS		# /proc
-file-system 	UMAPFS		# NULLFS + uid and gid remapping
-file-system 	UNION		# union file system
-file-system	SMBFS		# CIFS; also needs nsmb (below)
+#file-system 	UMAPFS		# NULLFS + uid and gid remapping
+#file-system 	UNION		# union file system
+#file-system	SMBFS		# CIFS; also needs nsmb (below)
 file-system	PTYFS		# /dev/pts/N support
-file-system	TMPFS		# Efficient memory file-system
+#file-system	TMPFS		# Efficient memory file-system
 #file-system	UDF		# experimental - OSTA UDF CD/DVD file-system
 #file-system	HFS		# experimental - Apple HFS+ (read-only)

 # File system options
-options 	QUOTA		# legacy UFS quotas
-options 	QUOTA2		# new, in-filesystem UFS quotas
+#options 	QUOTA		# legacy UFS quotas
+#options 	QUOTA2		# new, in-filesystem UFS quotas
 #options 	FFS_EI		# FFS Endian Independent support
-options 	WAPBL		# File system journaling support
+#options 	WAPBL		# File system journaling support
 #options 	UFS_DIRHASH	# UFS Large Directory Hashing - Experimental
-options 	NFSSERVER	# Network File System server
+#options 	NFSSERVER	# Network File System server
 #options 	FFS_NO_SNAPSHOT	# No FFS snapshot support
 #options 	EXT2FS_SYSTEM_FLAGS # makes ext2fs file flags (append and
 				# immutable) behave as system flags.
-options 	APPLE_UFS	# Apple UFS support in FFS
+#options 	APPLE_UFS	# Apple UFS support in FFS

 options 	NFS_BOOT_DHCP	# Support DHCP NFS root

 # Networking options
 #options 	GATEWAY		# packet forwarding
 options 	INET		# IP + ICMP + TCP + UDP
-options 	INET6		# IPV6
+#options 	INET6		# IPV6
 #options 	IPSEC		# IP security
 #options 	IPSEC_DEBUG	# debug for IP security
 #options 	MROUTING	# IP multicast routing
 #options 	PIM		# Protocol Independent Multicast
-options 	NETATALK	# AppleTalk networking protocols
-options 	PPP_BSDCOMP	# BSD-Compress compression support for PPP
-options 	PPP_DEFLATE	# Deflate compression support for PPP
-options 	PPP_FILTER	# Active filter support for PPP (requires bpf)
-options 	IPFILTER_LOG	# ipmon(8) log support
-options 	IPFILTER_LOOKUP	# ippool(8) support
-options 	IPFILTER_COMPAT # Compat for IP-Filter
+#options 	NETATALK	# AppleTalk networking protocols
+#options 	PPP_BSDCOMP	# BSD-Compress compression support for PPP
+#options 	PPP_DEFLATE	# Deflate compression support for PPP
+#options 	PPP_FILTER	# Active filter support for PPP (requires bpf)
+#options 	IPFILTER_LOG	# ipmon(8) log support
+#options 	IPFILTER_LOOKUP	# ippool(8) support
+#options 	IPFILTER_COMPAT # Compat for IP-Filter
 #options 	IPFILTER_DEFAULT_BLOCK	# block all packets by default
 #options 	TCP_DEBUG	# Record last TCP_NDEBUG packets with SO_DEBUG
 @@ -158,11 +165,11 @@

 # These options enable verbose messages for several subsystems.
 # Warning, these may compile large string tables into the kernel!
-options 	PCIVERBOSE	# verbose PCI device autoconfig messages
-options 	MIIVERBOSE	# verbose PHY autoconfig messages
+#options 	PCIVERBOSE	# verbose PCI device autoconfig messages
+#options 	MIIVERBOSE	# verbose PHY autoconfig messages
 #options 	PCI_CONFIG_DUMP	# verbosely dump PCI config space
-options 	SCSIVERBOSE	# human readable SCSI error messages
-options 	USBVERBOSE	# verbose USB device autoconfig messages
+#options 	SCSIVERBOSE	# human readable SCSI error messages
+#options 	USBVERBOSE	# verbose USB device autoconfig messages

 # wscons options
 #options 	WSEMUL_SUN			# sun terminal emulation
@@ -222,60 +229,60 @@
 pchb*	at pci? dev ? function ?	# PCI-Host bridges
 ppb*	at pci? dev ? function ?	# PCI-PCI bridges
 # XXX 'puc's aren't really bridges, but there's no better place for them here
-puc*	at pci? dev ? function ?	# PCI "universal" comm. cards
-lpt*	at puc? port ?			# || ports on > "universal" comm boards
+#puc*	at pci? dev ? function ?	# PCI "universal" comm. cards
+#lpt*	at puc? port ?			# || ports on > "universal" comm boards

 # PCI Network devices
-an*	at pci? dev ? function ?	# Aironet PC4500/PC4800 (802.11)
-ath*	at pci? dev ? function ?	# Atheros 5210/5211/5212 802.11
-atw*	at pci? dev ? function ?	# ADMtek ADM8211 (802.11)
-bge*	at pci? dev ? function ?	# Broadcom 570x Gigabit Ethernet
-bwi*	at pci? dev ? function ?	# Broadcom / Apple Airport Extreme
-ep*	at pci? dev ? function ?	# 3Com 3c59x
-epic*	at pci? dev ? function ?	# SMC EPIC/100 Ethernet
-ex*	at pci? dev ? function ?	# 3Com 90x[BC]
-fpa*	at pci? dev ? function ?	# DEC PCI FDDI (DEFPA) Controller
-fxp*	at pci? dev ? function ?	# Intel EtherExpress PRO 10+/100B
-gem*	at pci? dev ? function ?	# gmac ethernet
-#gm*	at pci? dev ? function ?	# gmac ethernet (old)
-gsip*	at pci? dev ? function ?	# NS83820 Gigabit Ethernet
-le*	at pci? dev ? function ?	# PCnet-PCI Ethernet
-lmc*	at pci? dev ? function ?	# Lan Media Corp SSI/HSSI/DS3
-mtd*	at pci? dev ? function ?	# Myson MTD803 3-in-1 Ethernet
-ne*	at pci? dev ? function ?	# NE2000-compatible Ethernet
-pcn*	at pci? dev ? function ?	# AMD PCnet-PCI Ethernet
-ral*	at pci? dev ? function ?	# Ralink Technology RT25x0 802.11a/b/g
-re*	at pci? dev ? function ?	# Realtek 8139C+/8169/8169S/8110S
-rtk*	at pci? dev ? function ?	# Realtek 8129/8139
-sf*	at pci? dev ? function ?	# Adaptec AIC-6915 Ethernet
-sip*	at pci? dev ? function ?	# SiS 900/7016 Ethernet
-skc*	at pci? dev ? function ?	# SysKonnect SK9821 Gigabit Ethernet
-sk*	at skc?				# SysKonnect SK9821 Gigabit Ethernet
-ste*	at pci? dev ? function ?	# Sundance ST-201 Ethernet
-stge*	at pci? dev ? function ?	# Sundance/Tamarack TC9021 Gigabit
-#ti*	at pci? dev ? function ?	# Alteon ACEnic gigabit Ethernet
-tl*	at pci? dev ? function ?	# ThunderLAN-based Ethernet
-tlp*	at pci? dev ? function ?	# DECchip 21x4x and clones
-vge*	at pci? dev ? function ?	# VIA VT612x Gigabit Ethernet
-vr*	at pci? dev ? function ?	# VIA Rhine Fast Ethernet
-wi*	at pci? dev ? function ?	# Intersil Prism Mini-PCI (802.11b)
-wm*	at pci? dev ? function ?	# Intel 82543/82544 gigabit
+# an*	at pci? dev ? function ?	# Aironet PC4500/PC4800 (802.11)
+# ath*	at pci? dev ? function ?	# Atheros 5210/5211/5212 802.11
+# atw*	at pci? dev ? function ?	# ADMtek ADM8211 (802.11)
+# bge*	at pci? dev ? function ?	# Broadcom 570x Gigabit Ethernet
+# bwi*	at pci? dev ? function ?	# Broadcom / Apple Airport Extreme
+# ep*	at pci? dev ? function ?	# 3Com 3c59x
+# epic*	at pci? dev ? function ?	# SMC EPIC/100 Ethernet
+# ex*	at pci? dev ? function ?	# 3Com 90x[BC]
+# fpa*	at pci? dev ? function ?	# DEC PCI FDDI (DEFPA) Controller
+# fxp*	at pci? dev ? function ?	# Intel EtherExpress PRO 10+/100B
+# gem*	at pci? dev ? function ?	# gmac ethernet
+# #gm*	at pci? dev ? function ?	# gmac ethernet (old)
+# gsip*	at pci? dev ? function ?	# NS83820 Gigabit Ethernet
+# le*	at pci? dev ? function ?	# PCnet-PCI Ethernet
+# lmc*	at pci? dev ? function ?	# Lan Media Corp SSI/HSSI/DS3
+# mtd*	at pci? dev ? function ?	# Myson MTD803 3-in-1 Ethernet
+# ne*	at pci? dev ? function ?	# NE2000-compatible Ethernet
+# pcn*	at pci? dev ? function ?	# AMD PCnet-PCI Ethernet
+# ral*	at pci? dev ? function ?	# Ralink Technology RT25x0 802.11a/b/g
+# re*	at pci? dev ? function ?	# Realtek 8139C+/8169/8169S/8110S
+# rtk*	at pci? dev ? function ?	# Realtek 8129/8139
+# sf*	at pci? dev ? function ?	# Adaptec AIC-6915 Ethernet
+# sip*	at pci? dev ? function ?	# SiS 900/7016 Ethernet
+# skc*	at pci? dev ? function ?	# SysKonnect SK9821 Gigabit Ethernet
+# sk*	at skc?				# SysKonnect SK9821 Gigabit Ethernet
+# ste*	at pci? dev ? function ?	# Sundance ST-201 Ethernet
+# stge*	at pci? dev ? function ?	# Sundance/Tamarack TC9021 Gigabit
+# #ti*	at pci? dev ? function ?	# Alteon ACEnic gigabit Ethernet
+# tl*	at pci? dev ? function ?	# ThunderLAN-based Ethernet
+# tlp*	at pci? dev ? function ?	# DECchip 21x4x and clones
+# vge*	at pci? dev ? function ?	# VIA VT612x Gigabit Ethernet
+# vr*	at pci? dev ? function ?	# VIA Rhine Fast Ethernet
+# wi*	at pci? dev ? function ?	# Intersil Prism Mini-PCI (802.11b)
+# wm*	at pci? dev ? function ?	# Intel 82543/82544 gigabit

 # PCI SCSI controllers
-adv*	at pci? dev ? function ?	# AdvanSys 1200[A,B], 9xx[U,UA] SCSI
-adw*	at pci? dev ? function ?	# AdvanSys 9x0UW[D], 3940U[2,3]W SCSI
-ahc*	at pci? dev ? function ?	# Adaptec 294x, aic78x0 SCSI
-bha*	at pci? dev ? function ?	# BusLogic 9xx SCSI
-esiop*	at pci? dev ? function ?	# NCR 53c8xx SCSI (enhanced)
-iha*	at pci? dev ? function ?	# Initio INIC-940/950 SCSI
-isp*	at pci? dev ? function ?	# Qlogic ISP 10x0/2xx0 SCSI/Fibre Chan
-mpt*	at pci? dev ? function ?	# LSILogic 9x9 and 53c1030
-pcscp*	at pci? dev ? function ?	# AMD Am53c974 PCscsi-PCI SCSI
-siop*	at pci? dev ? function ?	# NCR 53c8xx SCSI
-trm*	at pci? dev ? function ?	# Tekram DC-395U/UW/F, DC-315/U SCSI
+# adv*	at pci? dev ? function ?	# AdvanSys 1200[A,B], 9xx[U,UA] SCSI
+# adw*	at pci? dev ? function ?	# AdvanSys 9x0UW[D], 3940U[2,3]W SCSI
+# ahc*	at pci? dev ? function ?	# Adaptec 294x, aic78x0 SCSI
+# bha*	at pci? dev ? function ?	# BusLogic 9xx SCSI
+# esiop*	at pci? dev ? function ?	# NCR 53c8xx SCSI (enhanced)
+# iha*	at pci? dev ? function ?	# Initio INIC-940/950 SCSI
+# isp*	at pci? dev ? function ?	# Qlogic ISP 10x0/2xx0 SCSI/Fibre Chan
+# mpt*	at pci? dev ? function ?	# LSILogic 9x9 and 53c1030
+# pcscp*	at pci? dev ? function ?	# AMD Am53c974 PCscsi-PCI SCSI
+# siop*	at pci? dev ? function ?	# NCR 53c8xx SCSI
+# trm*	at pci? dev ? function ?	# Tekram DC-395U/UW/F, DC-315/U SCSI

 # Display devices
-# ofb*	at pci? dev ? function ?	# Generic Open Firmware Framebuffer
+#ofb*	at pci? dev ? function ?	# Generic Open Firmware Framebuffer
 # OFB_ENABLE_CACHE speeds up the console on many machines, but should
 # not be enabled on some older machines, such as the rev. A-D iMacs or any
 # O'Hare based machine that uses external cache like the PowerBook 3400c
@@ -286,17 +293,14 @@
 # instead.

 chipsfb*	at pci?	function ?	# C&T 65550
-gffb*		at pci?	function ?	# NVIDIA GeForce2 MX
 machfb*		at pci? function ?	# ATI Mach 64, Rage, Rage Pro
-tdvfb*		at pci? function ?	# 3Dfx Voodoo2
-r128fb*		at pci? function ?	# ATI Rage 128
-voodoofb*	at pci? function ?	# 3Dfx Voodoo3 
-
-# ATI Radeon. Still has problems on some hardware
-radeonfb*	at pci? function ?
-options 	RADEONFB_MMAP_BARS	# allow mmap()ing BARs - needed for X

-# generic PCI framebuffer, should work with everything supported by OF
+#radeonfb*	at pci? function ?	# ATI Radeon. R3xx is problematic
+#options 	RADEONFB_MMAP_BARS	# allow mmap()ing BARs - needed for X
+
+#voodoofb*	at pci? function ?	# 3Dfx Voodoo3 
+#tdvfb*		at pci? function ?	# 3Dfx Voodoo2
+#r128fb*	at pci? function ?	# ATI Rage 128
 genfb*		at pci? function ?

 # make sure the console display is always wsdisplay0
@@ -307,60 +311,60 @@

 # Other  PCI devices
 pciide* at pci? dev ? function ? flags 0x0000	# GENERIC pciide driver
-acardide* at pci? dev ? function ?	# Acard IDE controllers
-aceride* at pci? dev ? function ?	# Acer Lab IDE controllers
-ahcisata* 	at pci? dev ? function ?	# AHCI SATA controllers
-artsata* at pci? dev ? function ?	# Intel i31244 SATA controller
-cmdide* at pci? dev ? function ?	# CMD tech IDE controllers
-cypide* at pci? dev ? function ?	# Cypress IDE controllers
-hptide* at pci? dev ? function ?	# Triones/HighPoint IDE controllers
-iteide* at pci? dev ? function ?	# IT Express IDE controllers
-optiide* at pci? dev ? function ?	# Opti IDE controllers
-pdcide* at pci? dev ? function ?	# Promise IDE controllers
-pdcsata* at pci? dev ? function ?	# Promise SATA150 controllers
-satalink* at pci? dev ? function ?	# SiI SATALink controllers
-siside* at pci? dev ? function ?	# SiS IDE controllers
-slide*  at pci? dev ? function ?	# Symphony Labs IDE controllers
-stpcide*	at pci? dev ? function ?	# STMicro STPC IDE controllers
-viaide* at pci? dev ? function ?	# VIA/AMD/Nvidia IDE controllers
-wdc*	at pci? dev ? function ?	# Kauai ATA
-cbb*	at pci? dev ? function ?	# PCI-CardBus bridge
+#acardide* at pci? dev ? function ?	# Acard IDE controllers
+#aceride* at pci? dev ? function ?	# Acer Lab IDE controllers
+#ahcisata* 	at pci? dev ? function ?	# AHCI SATA controllers
+#artsata* at pci? dev ? function ?	# Intel i31244 SATA controller
+#cmdide* at pci? dev ? function ?	# CMD tech IDE controllers
+#cypide* at pci? dev ? function ?	# Cypress IDE controllers
+#hptide* at pci? dev ? function ?	# Triones/HighPoint IDE controllers
+#iteide* at pci? dev ? function ?	# IT Express IDE controllers
+#optiide* at pci? dev ? function ?	# Opti IDE controllers
+#pdcide* at pci? dev ? function ?	# Promise IDE controllers
+#pdcsata* at pci? dev ? function ?	# Promise SATA150 controllers
+#satalink* at pci? dev ? function ?	# SiI SATALink controllers
+#siside* at pci? dev ? function ?	# SiS IDE controllers
+#slide*  at pci? dev ? function ?	# Symphony Labs IDE controllers
+#stpcide*	at pci? dev ? function ?	# STMicro STPC IDE controllers
+#viaide* at pci? dev ? function ?	# VIA/AMD/Nvidia IDE controllers
+#wdc*	at pci? dev ? function ?	# Kauai ATA
+#cbb*	at pci? dev ? function ?	# PCI-CardBus bridge
 obio*	at pci? dev ? function ?

-acphy*	at mii? phy ?			# DAltima AC101 and AMD Am79c874 PHYs
-amhphy*	at mii? phy ?			# AMD 79c901 Ethernet PHYs
-bmtphy*	at mii? phy ?			# Broadcom BCM5201/BCM5202 PHYs
-brgphy*	at mii? phy ?			# Broadcom BCM5400 PHYs
-ciphy*	at mii? phy ?			# Cicada CS8201 Gig-E PHYs
-dmphy*	at mii? phy ?                   # Davicom DM9101 PHYs
-exphy*	at mii? phy ?			# 3Com internal PHYs
-glxtphy* at mii? phy ?			# Level One LXT-1000 PHYs
-gphyter* at mii? phy ?			# NS83861 Gig-E PHY
-icsphy*	at mii? phy ?			# Integrated Circuit Systems ICS189x
-ikphy*	at mii? phy ?			# Intel 82563 PHYs
-inphy*	at mii? phy ?			# Intel 82555 PHYs
-iophy*	at mii? phy ?			# Intel 82553 PHYs
-lxtphy*	at mii? phy ?			# Level One LXT-970 PHYs
-makphy* at mii? phy ?			# Marvell Semiconductor 88E1000 PHYs
-nsphy*	at mii? phy ?			# NS83840 PHYs
-nsphyter* at mii? phy ?			# NS83843 PHYs
-pnaphy* at mii? phy ?			# generic HomePNA PHYs
-qsphy*	at mii? phy ?			# Quality Semiconductor QS6612 PHYs
-rgephy* at mii? phy ?			# Realtek 8169S/8110S internal PHYs
-rlphy*	at mii? phy ?			# Realtek 8139/8201L PHYs
-sqphy*	at mii? phy ?			# Seeq 80220/80221/80223 PHYs
-tlphy*	at mii? phy ?			# ThunderLAN PHYs
-tqphy*	at mii? phy ?			# TDK Semiconductor PHYs
-ukphy*	at mii? phy ?			# generic unknown PHYs
-urlphy* at mii? phy ?			# Realtek RTL8150L internal PHYs
+# acphy*	at mii? phy ?			# DAltima AC101 and AMD Am79c874 PHYs
+# amhphy*	at mii? phy ?			# AMD 79c901 Ethernet PHYs
+# bmtphy*	at mii? phy ?			# Broadcom BCM5201/BCM5202 PHYs
+# brgphy*	at mii? phy ?			# Broadcom BCM5400 PHYs
+# ciphy*	at mii? phy ?			# Cicada CS8201 Gig-E PHYs
+# dmphy*	at mii? phy ?                   # Davicom DM9101 PHYs
+# exphy*	at mii? phy ?			# 3Com internal PHYs
+# glxtphy* at mii? phy ?			# Level One LXT-1000 PHYs
+# gphyter* at mii? phy ?			# NS83861 Gig-E PHY
+# icsphy*	at mii? phy ?			# Integrated Circuit Systems ICS189x
+# ikphy*	at mii? phy ?			# Intel 82563 PHYs
+# inphy*	at mii? phy ?			# Intel 82555 PHYs
+# iophy*	at mii? phy ?			# Intel 82553 PHYs
+# lxtphy*	at mii? phy ?			# Level One LXT-970 PHYs
+# makphy* at mii? phy ?			# Marvell Semiconductor 88E1000 PHYs
+# nsphy*	at mii? phy ?			# NS83840 PHYs
+# nsphyter* at mii? phy ?			# NS83843 PHYs
+# pnaphy* at mii? phy ?			# generic HomePNA PHYs
+# qsphy*	at mii? phy ?			# Quality Semiconductor QS6612 PHYs
+# rgephy* at mii? phy ?			# Realtek 8169S/8110S internal PHYs
+# rlphy*	at mii? phy ?			# Realtek 8139/8201L PHYs
+# sqphy*	at mii? phy ?			# Seeq 80220/80221/80223 PHYs
+# tlphy*	at mii? phy ?			# ThunderLAN PHYs
+# tqphy*	at mii? phy ?			# TDK Semiconductor PHYs
+# ukphy*	at mii? phy ?			# generic unknown PHYs
+# urlphy* at mii? phy ?			# Realtek RTL8150L internal PHYs

 # PCI serial interfaces
-com*	at puc? port ?			# 16x50s on "universal" comm boards
-cy*	at pci? dev ? function ?	# Cyclades Cyclom-Y serial boards
+#com*	at puc? port ?			# 16x50s on "universal" comm boards
+#cy*	at pci? dev ? function ?	# Cyclades Cyclom-Y serial boards
 #cz*	at pci? dev ? function ?	# Cyclades-Z multi-port serial boards

-bktr*   at      pci? dev ? function ?           # Brooktree video/audio capture/tuner
-radio*  at      bktr?
+#bktr*   at      pci? dev ? function ?           # Brooktree video/audio capture/tuner
+#radio*  at      bktr?

 bm*	at obio?			# bmac ethernet
 mc*	at obio?			# MACE ethernet
@@ -383,17 +387,17 @@
 pmu*	at obio?			# PMU, *Books and newer PowerMacs
 nadb*	at adb_bus?			# ADB bus enumerator, at cuda or pmu
 adbkbd* at nadb?			# ADB keyboard
-adbms*	at nadb?			# ADB mice and touchpads
-adbbt*	at nadb?			# button device found on *Books
+#adbms*	at nadb?			# ADB mice and touchpads
+#adbbt*	at nadb?			# button device found on *Books

 wskbd*		at wskbddev? console ?
-wsmouse*	at wsmousedev?
+#wsmouse*	at wsmousedev?

-battery* at pmu?		# legacy battery, for ohare-based PowerBooks
-smartbat* at pmu?		# Smart battery, found in newer *Books
+#battery* at pmu?		# legacy battery, for ohare-based PowerBooks
+#smartbat* at pmu?		# Smart battery, found in newer *Books

 iic0	at cuda0		# CUDA's IIC bus
-sgsmix0 at iic0 addr 0x8a	# additional mixer found in beige G3
+#sgsmix0 at iic0 addr 0x8a	# additional mixer found in beige G3
 				# use with awacs

 zsc*	at obio?
@@ -410,28 +414,28 @@
 iic*	at ki2c?
 dbcool*	at ki2c?			# dbCool thermal monitor & fan control

-deq*	at ki2c?			# mixer/equalizer, needed by snapper
-wi*	at obio?			# AirMac
-snapper* at obio?			# Snapper audio device
-
-cardslot* at cbb?
-cardbus* at cardslot?
-pcmcia*	at cardslot?
-
-com*	at pcmcia? function ?		# Modems and serial cards
-wdc*	at pcmcia? function ?		# PCMCIA IDE controllers
-ep*	at pcmcia? function ?		# 3Com 3c589 and 3c562 Ethernet
-mbe*	at pcmcia? function ?		# MB8696x based Ethernet
-ne*	at pcmcia? function ?		# NE2000-compatible Ethernet
-awi*	at pcmcia? function ?		# BayStack 650/660 (802.11FH/DS)
-wi*	at pcmcia? function ?		# Lucent WaveLan IEEE (802.11)
-ath*	at cardbus? function ?	# Atheros 5210/5211/5212 802.11
-atw*	at cardbus? function ?	# ADMtek ADM8211 (802.11)
-ex*	at cardbus? function ?	# 3Com 3C575TX
-tlp*	at cardbus? function ?	# DECchip 21143
-ral*	at cardbus? function ?	# Ralink Technology RT25x0 802.11a/b/g
-rtk*	at cardbus? function ?	# Realtek 8129/8139
-rtw*	at cardbus? function ?	# Realtek 8180L (802.11)
+#deq*	at ki2c?			# mixer/equalizer, needed by snapper
+#wi*	at obio?			# AirMac
+#snapper* at obio?			# Snapper audio device
+
+#cardslot* at cbb?
+#cardbus* at cardslot?
+#pcmcia*	at cardslot?
+
+#com*	at pcmcia? function ?		# Modems and serial cards
+#wdc*	at pcmcia? function ?		# PCMCIA IDE controllers
+#ep*	at pcmcia? function ?		# 3Com 3c589 and 3c562 Ethernet
+#mbe*	at pcmcia? function ?		# MB8696x based Ethernet
+#ne*	at pcmcia? function ?		# NE2000-compatible Ethernet
+#awi*	at pcmcia? function ?		# BayStack 650/660 (802.11FH/DS)
+#wi*	at pcmcia? function ?		# Lucent WaveLan IEEE (802.11)
+#ath*	at cardbus? function ?	# Atheros 5210/5211/5212 802.11
+#atw*	at cardbus? function ?	# ADMtek ADM8211 (802.11)
+#ex*	at cardbus? function ?	# 3Com 3C575TX
+#tlp*	at cardbus? function ?	# DECchip 21143
+#ral*	at cardbus? function ?	# Ralink Technology RT25x0 802.11a/b/g
+#rtk*	at cardbus? function ?	# Realtek 8129/8139
+#rtw*	at cardbus? function ?	# Realtek 8180L (802.11)

 # Cryptographic Devices

@@ -444,113 +448,113 @@
 scsibus* at scsi?

 sd*	at scsibus? target ? lun ?	# SCSI disks
-st*	at scsibus? target ? lun ?	# SCSI tape drives
+#st*	at scsibus? target ? lun ?	# SCSI tape drives
 cd*	at scsibus? target ? lun ?	# SCSI CD-ROM drives
-ch*	at scsibus? target ? lun ?	# SCSI autochangers
-ss*	at scsibus? target ? lun ?	# SCSI scanners
-uk*	at scsibus? target ? lun ?	# SCSI unknown
+#ch*	at scsibus? target ? lun ?	# SCSI autochangers
+#ss*	at scsibus? target ? lun ?	# SCSI scanners
+#uk*	at scsibus? target ? lun ?	# SCSI unknown

 wdc*	at obio? flags 0x1
 atabus* at ata?
 wd*	at atabus? drive ? flags 0x0000

-atapibus* at atapi?
+#atapibus* at atapi?

-cd*	at atapibus? drive ? flags 0x0000	# ATAPI CD-ROM drives
-sd*	at atapibus? drive ? flags 0x0000	# ATAPI disk drives
-uk*	at atapibus? drive ? flags 0x0000	# ATAPI unknown
+#cd*	at atapibus? drive ? flags 0x0000	# ATAPI CD-ROM drives
+#sd*	at atapibus? drive ? flags 0x0000	# ATAPI disk drives
+#uk*	at atapibus? drive ? flags 0x0000	# ATAPI unknown

 # PCI USB controllers
-ohci*	at pci? dev ? function ?	# USB Open Host Controller
-ehci*	at pci? dev ? function ?	# USB Enhanced Host Controller
+#ohci*	at pci? dev ? function ?	# USB Open Host Controller
+#ehci*	at pci? dev ? function ?	# USB Enhanced Host Controller

-ohci*	at cardbus? function ?	# USB Open Host Controller
-ehci*	at cardbus? function ?	# USB Enhanced Host Controller
+#ohci*	at cardbus? function ?	# USB Open Host Controller
+#ehci*	at cardbus? function ?	# USB Enhanced Host Controller

-slhci*	at pcmcia? function ?	# ScanLogic SL811HS
+#slhci*	at pcmcia? function ?	# ScanLogic SL811HS

-usb*	at ehci?					# USB bus support
-usb*	at ohci?					# USB bus support
-usb*	at slhci?					# USB bus support
-uhub*	at usb?						# USB Hubs
-uhub*	at uhub? port ?
+#usb*	at ehci?					# USB bus support
+#usb*	at ohci?					# USB bus support
+#usb*	at slhci?					# USB bus support
+#uhub*	at usb?						# USB Hubs
+#uhub*	at uhub? port ?

-uhidev*	at uhub? port ? configuration ? interface ?	# USB HID device
+#uhidev*	at uhub? port ? configuration ? interface ?	# USB HID device

-pbms*	at uhidev? reportid ?				# PowerBook 15" mouse
+#pbms*	at uhidev? reportid ?				# PowerBook 15" mouse

-ums*	at uhidev? reportid ?				# USB Mice
+#ums*	at uhidev? reportid ?				# USB Mice

-ukbd*	at uhidev? reportid ?				# USB Keyboards
+#ukbd*	at uhidev? reportid ?				# USB Keyboards

-uthum*	at uhidev? reportid ?				# TEMPerHUM sensors
+#uthum*	at uhidev? reportid ?				# TEMPerHUM sensors

-ucycom*	at uhidev? reportid ?				# USB serial adapter
+#ucycom*	at uhidev? reportid ?				# USB serial adapter

-uhid*	at uhidev? reportid ?				# USB Generic HID
+#uhid*	at uhidev? reportid ?				# USB Generic HID
 -ulpt*	at uhub? port ? configuration ? interface ?	# USB Printer
+#ulpt*	at uhub? port ? configuration ? interface ?	# USB Printer

-umodem*	at uhub? port ? configuration ?			# USB Modem
-ucom*	at umodem?
+#umodem*	at uhub? port ? configuration ?			# USB Modem
+#ucom*	at umodem?

-ubsa*	at uhub? port ?					# Belkin serial adapter
-ucom*	at ubsa? portno ?
+#ubsa*	at uhub? port ?					# Belkin serial adapter
+#ucom*	at ubsa? portno ?

-uplcom* at uhub? port ?					# Prolific serial
-ucom* at uplcom? portno ?
+#uplcom* at uhub? port ?					# Prolific serial
+#ucom* at uplcom? portno ?

-uftdi* at uhub? port ?					# FTDI serial
-ucom* at uftdi? portno ?
+#uftdi* at uhub? port ?					# FTDI serial
+#ucom* at uftdi? portno ?

-uhso*	at uhub? port ? configuration ?			# Option N.V. Wireless WAN modems
+#uhso*	at uhub? port ? configuration ?			# Option N.V. Wireless WAN modems

-umass*	at uhub? port ? configuration ? interface ?	# USB Mass Storage
+#umass*	at uhub? port ? configuration ? interface ?	# USB Mass Storage

-uaudio*	at uhub? port ? configuration ?			# USB audio
+#uaudio*	at uhub? port ? configuration ?			# USB audio

 # D-Link DSB-R100 USB FM radio tuner
-udsbr* at uhub? port ?
-radio* at udsbr?
+#udsbr* at uhub? port ?
+#radio* at udsbr?

 # USB Ethernet adapters
-aue*	at uhub? port ?		# ADMtek AN986 Pegasus based adapters
-axe*	at uhub? port ?		# ASIX AX88172 based adapters
-cue*	at uhub? port ?		# CATC USB-EL1201A based adapters
-kue*	at uhub? port ?		# Kawasaki LSI KL5KUSB101B based adapters
-url*	at uhub? port ?		# Realtek RTL8150L based adapters
-udav*	at uhub? port ?		# Davicom DM9601 based adapters
-
-ukyopon* at uhub? port ?				# Kyocera AIR-EDGE PHONE
-ucom*	at ukyopon? portno ?
-
-uscanner* at uhub? port ?				# USB scanners
-uyap* at uhub? port ?					# Y@P firmware loader
-ugen*	at uhub? port ? configuration ? interface ?	# USB Generic driver
+#aue*	at uhub? port ?		# ADMtek AN986 Pegasus based adapters
+#axe*	at uhub? port ?		# ASIX AX88172 based adapters
+#cue*	at uhub? port ?		# CATC USB-EL1201A based adapters
+#kue*	at uhub? port ?		# Kawasaki LSI KL5KUSB101B based adapters
+#url*	at uhub? port ?		# Realtek RTL8150L based adapters
+#udav*	at uhub? port ?		# Davicom DM9601 based adapters
+
+#ukyopon* at uhub? port ?				# Kyocera AIR-EDGE PHONE
+#ucom*	at ukyopon? portno ?
+
+#uscanner* at uhub? port ?				# USB scanners
+#uyap* at uhub? port ?					# Y@P firmware loader
+#ugen*	at uhub? port ? configuration ? interface ?	# USB Generic driver

 # USB 802.11 adapters
-atu*	at uhub? port ?		# Atmel at76c50x 802.11b
-otus*	at uhub? port ?		# Atheros AR9001U
-ural*	at uhub? port ?		# Ralink Technology RT2500USB 802.11a/b/g
-rum*	at uhub? port ?		# Ralink Technology RT2501/RT2601 802.11a/b/g
+#atu*	at uhub? port ?		# Atmel at76c50x 802.11b
+#otus*	at uhub? port ?		# Atheros AR9001U
+#ural*	at uhub? port ?		# Ralink Technology RT2500USB 802.11a/b/g
+#rum*	at uhub? port ?		# Ralink Technology RT2501/RT2601 802.11a/b/g
 #zyd*	at uhub? port ?		# Zydas ZD1211

 # PCI IEEE1394 controllers
-fwohci*	at pci? dev ? function ?	# IEEE1394 Open Host Controller
+#fwohci*	at pci? dev ? function ?	# IEEE1394 Open Host Controller

 # CardBus IEEE1394 controllers 
 #fwohci*	at cardbus? function ?	# IEEE1394 Open Host Controller

-ieee1394if* at fwohci?
-fwip*	at ieee1394if?			# IP over IEEE1394
-sbp*	at ieee1394if? euihi ? euilo ?
+#ieee1394if* at fwohci?
+#fwip*	at ieee1394if?			# IP over IEEE1394
+#sbp*	at ieee1394if? euihi ? euilo ?
  # Audio Devices

 # PCI audio devices
 #clcs*	at pci? dev ? function ?	# Cirrus Logic CS4280
 #cmpci*	at pci? dev ? function ?	# C-Media CMI8338/8738
-eap*	at pci? dev ? function ?	# Ensoniq AudioPCI
+#eap*	at pci? dev ? function ?	# Ensoniq AudioPCI
 #eso*	at pci? dev ? function ?	# ESS Solo-1 PCI AudioDrive
 #fms*	at pci? dev ? function ?	# Forte Media FM801
 #sv*	at pci? dev ? function ?	# S3 SonicVibes
@@ -561,7 +565,7 @@
 #opl*	at fms?

 # Audio support
-audio*	at audiobus?
+#audio*	at audiobus?

 # MPU 401 UARTs
 #mpu*	at cmpci?
@@ -569,23 +573,23 @@
 #mpu*	at fms?

 # MIDI support
-midi*	at eap?			# 137[01] MIDI port
+#midi*	at eap?			# 137[01] MIDI port
 #midi*	at mpu?			# MPU 401

 #
 # accept filters
-pseudo-device   accf_data		# "dataready" accept filter
-pseudo-device   accf_http		# "httpready" accept filter
+#pseudo-device   accf_data		# "dataready" accept filter
+#pseudo-device   accf_http		# "httpready" accept filter

 #pseudo-device 	crypto			# /dev/crypto device
 					# (disabled, requires generic softints)
 #pseudo-device	swcrypto		# software crypto implementation
-pseudo-device	vnd			# disk-like interface to files
+#pseudo-device	vnd			# disk-like interface to files
 #options 	VND_COMPRESSION		# compressed vnd(4)
-pseudo-device	ccd			# concatenated/striped disk devices
+#pseudo-device	ccd			# concatenated/striped disk devices
 #pseudo-device	cgd			# cryptographic disk devices
-pseudo-device	raid			# RAIDframe disk driver
-options 	RAID_AUTOCONFIG		# auto-configuration of RAID components
+#pseudo-device	raid			# RAIDframe disk driver
+#options 	RAID_AUTOCONFIG		# auto-configuration of RAID components
 # Options to enable various other RAIDframe RAID types.
 # options 	RF_INCLUDE_EVENODD=1
 # options 	RF_INCLUDE_RAID5_RS=1
@@ -594,34 +598,34 @@
 # options 	RF_INCLUDE_INTERDECLUSTER=1
 # options 	RF_INCLUDE_PARITY_DECLUSTERING=1
 # options 	RF_INCLUDE_PARITY_DECLUSTERING_DS=1
-pseudo-device	fss			# file system snapshot device
-pseudo-device	md			# memory disk device
+#pseudo-device	fss			# file system snapshot device
+#pseudo-device	md			# memory disk device
 pseudo-device	loop			# network loopback
 pseudo-device	bpfilter		# packet filter
-pseudo-device	ipfilter		# IP filter (firewall) and NAT
-pseudo-device	ppp			# Point-to-Point Protocol
-pseudo-device	pppoe			# PPP over Ethernet (RFC 2516)
-pseudo-device	sl			# Serial Line IP
-pseudo-device	tun			# network tunneling over tty
-pseudo-device	tap			# virtual Ethernet
+#pseudo-device	ipfilter		# IP filter (firewall) and NAT
+#pseudo-device	ppp			# Point-to-Point Protocol
+#pseudo-device	pppoe			# PPP over Ethernet (RFC 2516)
+#pseudo-device	sl			# Serial Line IP
+#pseudo-device	tun			# network tunneling over tty
+#pseudo-device	tap			# virtual Ethernet
 #pseudo-device	gre			# generic L3 over IP tunnel
-pseudo-device	gif			# IPv[46] over IPv[46] tunnel (RFC1933)
+#pseudo-device	gif			# IPv[46] over IPv[46] tunnel (RFC1933)
 #pseudo-device	faith			# IPv[46] tcp relay translation i/f
-pseudo-device	stf			# 6to4 IPv6 over IPv4 encapsulation
-pseudo-device	vlan			# IEEE 802.1q encapsulation
-pseudo-device	bridge			# simple inter-network bridging
+#pseudo-device	stf			# 6to4 IPv6 over IPv4 encapsulation
+#pseudo-device	vlan			# IEEE 802.1q encapsulation
+#pseudo-device	bridge			# simple inter-network bridging
 #options 	BRIDGE_IPF		# bridge uses IP/IPv6 pfil hooks too
-pseudo-device	agr			# IEEE 802.3ad link aggregation
+#pseudo-device	agr			# IEEE 802.3ad link aggregation
 pseudo-device	pty			# pseudo-terminals
 pseudo-device	openfirm		# /dev/openfirm
 pseudo-device	wsmux			# mouse and keyboard multiplexer
-pseudo-device	swwdog			# software watchdog driver - swwdog(4)
+#pseudo-device	swwdog			# software watchdog driver - swwdog(4)
 pseudo-device	clockctl		# user control of clock subsystem
 pseudo-device	ksyms			# /dev/ksyms
-pseudo-device	nsmb			# SMB requester
+#pseudo-device	nsmb			# SMB requester
 #pseudo-device	pf			# PF packet filter
 #pseudo-device	pflog			# PF log if
-pseudo-device	putter			# for puffs and pud
+#pseudo-device	putter			# for puffs and pud

 # userland interface to drivers, including autoconf and properties retrieval
 pseudo-device   drvctl





>How-To-Repeat:

>Fix:

>Release-Note:

>Audit-Trail:
From: Michael <macallan@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600: Add support for powermac 7200/PPC 601
Date: Sun, 16 Feb 2014 21:25:54 -0500

 Thanks!

 >  2) Use rtc realtime register instead of timebase register, which 601 doesn't have.  It's possible I may have missed some asm calls to mftb/mttb
 > 
 >  3) alignment exceptions - the 601 will throw alignment exceptions if operands cross page boundaries.   I updated trap.c to handle that, and  changed memcpy.S to always use byte-copy (not word-copy) when in kernel.  There may be a more optimal way to handle. Also, I'm not that familiar with other powerpc's, so my handler changes may need tweaking for other cpus

 That's strange, port-rs6k and port-prep were supposed to work on 601s. I never verified this though.

 >   4) use CPUFLAGS+= -mcpu=601.  Also, the kernel apparently has to be  < 4M to netboot

 That seems to be an OF limitation, I've seen it on other macs as well.

 >   5) /platinum video - video console is not working. I'm not that familar with this area, but I'll be glad to test any changes

 I'm fairly familiar with this kind of work ;)

 have fun
 Michael

From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
To: gnats-bugs@NetBSD.org
Cc: tsutsui@ceres.dti.ne.jp
Subject: Re: port-macppc/48600: Add support for powermac 7200/PPC 601
Date: Mon, 17 Feb 2014 21:04:40 +0900

 >  >   4) use CPUFLAGS+= -mcpu=601.  Also, the kernel apparently has to be  < 4M to netboot
 >  
 >  That seems to be an OF limitation, I've seen it on other macs as well.

 Probably OF's real-base problem.
 http://www.netbsd.org/ports/macppc/faq.html#ofw-real-base

 ---
 Izumi Tsutsui

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Thu, 6 Mar 2014 08:45:30 -0700

 I saw the changes got checked in, thanks for doing that.

 When I tried to update and compile today I got DSI errors in init:

 ...
 nfs_boot: trying DHCP/BOOTP
 nfs_boot: DHCP next-server: 192.168.0.3
 nfs_boot: my_name=macppc
 nfs_boot: my_addr=192.168.0.99
 nfs_boot: my_mask=255.255.255.0
 nfs_boot: gateway=192.168.0.1
 root on 192.168.0.3:/export/client/root
 root file system type: nfs
 trap: pid 1.1 (init): user read DSI trap @ 0xa0 by 0xfdfe45d0 (DSISR 0x40000000, err=14)

 Are there other things going on in ppc that could be causing this?

From: Michael <macallan@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Fri, 7 Mar 2014 08:26:21 -0500

 I've seen those too, didn't get around to look any closer. Must be a
 userland thing that crept in between Feb. 18 and the time I committed
 the 601 stuff - a userland from that time, with your patches, works
 with a recent kernel.

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Fri, 7 Mar 2014 07:25:19 -0700

 After updating again today the error went away.  Everything appears to be running.   So it must have been userland bumps.

 I was going to try messing with the video again.  I haven't been able to find any info regarding platinum video other than some files in the linux kernel which I haven't dug into yet.

 Do you know of any other sources of info about it?  Or do you think it be easier just to start with the valkyriefb.c and go from there?

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: port-macppc/48600
Date: Mon, 13 Oct 2014 10:45:09 -0400

 I've been working on this again recently.  Basically I adapted the
 valkyriefb code with linux platinumfb.  So far I can turn on the
 monitor, switch between virtual screens, see stuff being printed out
 when the kernel is booting with green and black on a white background.

 But the onscreen/typed characters look like garbage.  I've been
 printing out rasops_info such as:

 	      ri->ri_depth, ri->ri_width, ri->ri_height,
 		      ri->ri_stride, (uint32_t)ri->ri_bits,
 		      ri->ri_font->fontheight,
 		      ri->ri_font->fontwidth

 getting
  RASTER depth 8 width 640 height 480 stride 640 addr d5460000
  RASTER fonth 15 fontd 8

 and don't see anything unusual.  Anyone have suggestions on what else
 I could be looking for?

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Mon, 13 Oct 2014 10:50:37 -0400

 I've been working on this again recently.  Basically I adapted the
 valkyriefb code with linux platinumfb.  So far I can turn on the
 monitor, switch between virtual screens, see stuff being printed out
 when the kernel is booting with green and black on a white background.

 But the onscreen/typed characters look like garbage.  I've been
 printing out rasops_info such as:

 	      ri->ri_depth, ri->ri_width, ri->ri_height,
 		      ri->ri_stride, (uint32_t)ri->ri_bits,
 		      ri->ri_font->fontheight,
 		      ri->ri_font->fontwidth

 getting
  RASTER depth 8 width 640 height 480 stride 640 addr d5460000
  RASTER fonth 15 fontd 8

 and don't see anything unusual.  Anyone have suggestions on what else
 I could be looking at?

From: Michael <macallan@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Mon, 13 Oct 2014 11:17:45 -0400

 What does the garbage look like?
 ( got a smartphone? Just take a picture and mail it to me. )
 Is the cursor recognizeable? Is the garbage consistent, as in same
 character produces same pattern every time, different character
 produces different pattern?
 The parameters look sane enough.

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Mon, 13 Oct 2014 12:26:50 -0400

 I sent a screenshot to your email.  I can't see a cursor and would say
 it looks consistent.

 If there is any other info I can provide, let me know.

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Mon, 13 Oct 2014 17:03:44 -0400

 After staring at this a little more, it seems like the horizontal
 pixel lines are not lined up.  It kind of looks to me like each pixel
 line is getting shifted to the right and not starting at the left edge
 of screen.

 I can tell this because I see same pattern of text repeated but
 shifted when hitting return in a login terminal.

From: Michael <macallan@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Tue, 14 Oct 2014 06:12:43 -0400

 Thanks, I got the screenshot.

 That looks like the stride or width is wrong. My guess is that the
 stride is too short, judging by the way the bands are tilted. I'd
 recommend scribbling into video memory by hand - just draw a vertical
 line in the middle of a blank screen and make the kernel stop right
 there so you can look at it. That should make it more obvious where
 things go wrong.
 Might be a side effect of a video mode mismatch, something like the
 video hardware running at 800x600 and the drawing routines assuming
 640x480.

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Tue, 14 Oct 2014 11:49:41 -0400

 There definitely was a problem with my sc_linebytes calculation. I
 missed some hardcoded fudge-factor; so after including that change, it
 worked!

 I plan to test a few of the other 8bit modes and submit a new PR with
 code changes if those pan out, if that sounds ok.  Would it be
 worthwhile trying to get 16 or 32 bit modes working, especially if
 this is only for console?

 Thanks again for the help and quick responses.

From: Michael <macallan@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Tue, 14 Oct 2014 21:43:41 -0400

 More than 8 bit depth would be useful for X, there are a few drivers
 which run wsdisplay in 8 bit but switch to 16 or 32 bit for X ( by
 catching ioctl(WSDISPLAYIO_SMODE) ), for example igsfb, crmfb,
 cgfourteen, omapfb, voyagerfb etc. - mostly hardware that does or did
 not have native Xorg drivers.
 Sure, X on a dumb framebuffer isn't exactly fast but in my opinionat
 least, there are enough situations where slow X beats no X.

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Wed, 29 Oct 2014 16:28:58 -0400

 Here is what I've done so far to get the platinum console working.  8
 bit seems fine, but 16 & 32 bit still have colormap issues.  Files are
 appended below.

 Some things I wasn't sure about:

 1) What is the framebuffer pixel format?  The 32 & 16 bit depth colors
 sometimes worked, but I was overriding ri_devcmap with CMY. I used
 options RASOPS_SMALL 
 in the kernel to eliminate issues with RI_BSWAP which may not
 correctly tied in for all the rasops*.c files.  I think stamp[] still
 needs to be byteswapped in some places.  Also, what if anything should
 be written to the cmap registers in 16 & 32 bit modes...

 2) Is mapiodev() required?  I didn't see it used for any other
 framebuffer drivers so wasn't sure.  Also, I had to use out8/in8/*
 from pio.h when writing hardware registers.

 3) Other things I wasn't sure about are marked with XXX

 The reason I was attempting to get 16 & 32 bit consoles modes working
 is because I thought it would be easier to do that first, before
 trying for X.

 I was still planning to try and see how far I can get with X (at least
 8 bpp), but I'm not really sure what's involved other than what is
 mentioned in wsdisplay(9).  As usual, I'll be glad to test any changes
 and am open to any suggestions.

 Feel free to change this code in any way...

 Changed files:
  sys/arch/powerpc/oea/ofw_autoconf.c
  sys/arch/macppc/conf/files.macppc
  sys/arch/macppc/conf/GENERIC_601
  sys/dev/wscons/wsconsio.h
  src/sys/dev/rasops/rasops24.c
 New files:
  sys/arch/macppc/dev/platinumfb.c
  sys/arch/macppc/dev/platinumfbreg.h

 Index: sys/arch/powerpc/oea/ofw_autoconf.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/powerpc/oea/ofw_autoconf.c,v
 retrieving revision 1.20
 diff -b -u -r1.20 ofw_autoconf.c
 --- sys/arch/powerpc/oea/ofw_autoconf.c	18 Feb 2014 12:27:15 -0000	1.20
 +++ sys/arch/powerpc/oea/ofw_autoconf.c	29 Oct 2014 20:23:36 -0000
 @@ -230,6 +230,14 @@
  		copy_disp_props(dev, ca->ca_node, dict);
  	}

 +	/*
 +	 * XXX can't read video properties from openfirmware
 +	 * for platinum.  Will parse some info later in attach function
 +	 */
 +	if (device_is_a(dev, "platinumfb")) {
 +                return;
 +	}
 +
  #if NGTPCI > 0
  	if (device_is_a(dev, "gtpci")) {
  		extern struct gtpci_prot gtpci0_prot, gtpci1_prot;
 Index: sys/arch/macppc/conf/files.macppc
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/macppc/conf/files.macppc,v
 retrieving revision 1.101
 diff -b -u -r1.101 files.macppc
 --- sys/arch/macppc/conf/files.macppc	11 Oct 2014 07:03:09 -0000	1.101
 +++ sys/arch/macppc/conf/files.macppc	29 Oct 2014 20:23:38 -0000
 @@ -307,3 +307,7 @@
  attach valkyriefb at mainbus
  file arch/macppc/dev/valkyriefb.c			valkyriefb
  defflag opt_valkyriefb.h VALKYRIEFB_DEBUG
 +
 +device platinumfb: wsemuldisplaydev, rasops8, rasops15, rasops32, vcons, videomode
 +attach platinumfb at mainbus
 +file arch/macppc/dev/platinumfb.c			platinumfb
 Index: sys/arch/macppc/conf/GENERIC_601
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/macppc/conf/GENERIC_601,v
 retrieving revision 1.7
 diff -b -u -r1.7 GENERIC_601
 --- sys/arch/macppc/conf/GENERIC_601	21 Oct 2014 08:49:55 -0000	1.7
 +++ sys/arch/macppc/conf/GENERIC_601	29 Oct 2014 20:23:40 -0000
 @@ -169,6 +169,7 @@
  options 	WS_DEFAULT_BG=WSCOL_LIGHT_WHITE
  options 	WS_KERNEL_FG=WSCOL_GREEN
  options 	WS_KERNEL_BG=WSCOL_LIGHT_WHITE
 +options         WSDISPLAY_SCROLLSUPPORT

  #options 	WSDISPLAY_COMPAT_RAWKBD		# can get raw scancodes
  options 	FONT_GALLANT12x22
 @@ -222,6 +223,12 @@
  # official Macintosh firmware from 3Dfx. The others should work but are
  # untested with OF 1.0.5

 +platinumfb* at mainbus?			# platinum built in video
 +
 +# XXX text looks byteswapped in 16/32 depths without this,
 +# think rasops15.c/rasops32.c stamp[] needs some bswapping
 +options RASOPS_SMALL 
 +
  #gffb*		at pci?	function ?	# NVIDIA GeForce2 MX
  #machfb*		at pci? function ?	# ATI Mach 64, Rage, Rage Pro
  #r128fb*		at pci? function ?	# ATI Rage 128
 Index: sys/dev/wscons/wsconsio.h
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/wscons/wsconsio.h,v
 retrieving revision 1.108
 diff -b -u -r1.108 wsconsio.h
 --- sys/dev/wscons/wsconsio.h	29 Apr 2013 13:39:47 -0000	1.108
 +++ sys/dev/wscons/wsconsio.h	29 Oct 2014 20:23:42 -0000
 @@ -334,6 +334,7 @@
  #define WSDISPLAY_TYPE_OMAP3	57	/* OMAP 3530 */
  #define WSDISPLAY_TYPE_WINDERMERE 58	/* SoC for EPOC32 Series 5mx */
  #define WSDISPLAY_TYPE_CLPS711X	59	/* CL PS-711x  */
 +#define WSDISPLAY_TYPE_PLATINUM	60	/* Apple onboard video 'platinum' */

  /* Basic display information.  Not applicable to all display types. */
  struct wsdisplay_fbinfo {
 Index: sys/dev/rasops/rasops24.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/rasops/rasops24.c,v
 retrieving revision 1.29
 diff -b -u -r1.29 rasops24.c
 --- sys/dev/rasops/rasops24.c	25 Jul 2011 18:02:47 -0000	1.29
 +++ sys/dev/rasops/rasops24.c	29 Oct 2014 20:23:44 -0000
 @@ -141,7 +141,7 @@
  	clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];

  	if (uc == ' ') {
 -		u_char c = clr[0];
 +	    u_char c = clr[0]; /* XXX this doesn't look right */
  		while (height--) {
  			dp = rp;
  			rp += ri->ri_stride;
 ===================================================================
 ==== new file
 sys/arch/macppc/dev/platinumfb.c
 ===================================================================
 /*
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */

 /* A console driver for Apple's Platinum onboard video controller,
  * found in (all?) Catalyst logic boards including the Powermac 7200.
  *
  * Used valkyriefb.c from NetBSD, and platinumfb.c/platinumfb.h from
  * Linux sources as templates.
  *
  * Platinum is broken regarding openfirmware video variables.  In OF,
  * for a powermac 7200, doing "dev /platinum .properties" results in:
  *
  *	name                    platinum
  *	device_type             display
  *	model                   AAPL,343S1184
  *	AAPL,connector          monitor
  *	reg                     F8000000  00000800
  *	                        F1000000  01000000
  *	AAPL,interrupts         0000001E
  *
  * The first reg is the register set, and the second is for the
  * framebuffer.  There is also a set of colormap registers hardcoded
  * in platinumfbreg.h that (I think) aren't in openfirmware.
  *
  * powermac 7200 VRAM min and max limits are 1 and 4 Mb respectively.
  * OF claims 16M so we don't use that value.  If other machines can
  * can have more or less VRAM this code will need to be modified
  */

 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: platinumfb.c,v 1.1 2014/10/31 12:00:00 macallan Exp $");

 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/device.h>

 #include <dev/ofw/openfirm.h>

 #include <machine/autoconf.h>
 #include <machine/pio.h>

 #include <dev/wscons/wsdisplayvar.h>
 #include <dev/wscons/wsconsio.h>
 #include <dev/wsfont/wsfont.h>
 #include <dev/rasops/rasops.h>
 #include <dev/wscons/wsdisplay_vconsvar.h>

 #include <dev/videomode/videomode.h>

 #include <arch/macppc/dev/platinumfbreg.h>

 #include "opt_wsemul.h"

 struct platinumfb_setting {
         char vmode_name[24];
 	int32_t width;
 	int32_t height;
     	uint8_t freq;
 	uint8_t macmode;

 	int32_t	fb_offset;
 	int32_t	pitch[3];
 	uint32_t regs[26];
 	uint8_t offset[3];
 	uint8_t mode[3];
 	uint8_t dacula_ctrl[3];
 	uint8_t clock_params[2][2];
 };

 struct platinumfb_softc {
 	device_t sc_dev;
 	int sc_node;

         uint8_t *sc_reg;
 	uint32_t sc_reg_size;

     	uint8_t *sc_cmap;
 	uint32_t sc_cmap_size;

 	uint8_t *sc_fb;
 	uint32_t sc_fb_size;

 	int sc_depth;
 	int sc_width, sc_height, sc_linebytes;
 	const struct videomode *sc_videomode;
 	uint8_t sc_modereg;

         int sc_mode;   /* XXX needed ? */
         /* uint32_t sc_bg; */ /* XXX needed ? */

 	u_char sc_cmap_red[256];
 	u_char sc_cmap_green[256];
 	u_char sc_cmap_blue[256];	

 	struct vcons_data vd;

         uint8_t sc_cmode;
         uint8_t sc_dac_type;
         uint32_t sc_vram;
         struct platinumfb_setting *sc_pfs;
 };

 #define DIV2	0x20
 #define DIV4	0x40
 #define DIV8	0x60
 #define DIV16	0x80

 static struct platinumfb_setting platinum_5 = {
     "640x480x60",
     640, 480, 60, 5,
     0x1010,
     { 672, 1312, 2592 },
     { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
       0, 0x15e, 0xc8, 0x18, 0x18f, 0x2f, 0x35, 0x3e,
       0x42, 0x182, 0x18e, 0x41a, 0x418, 2, 7, 0x44,
       0x404, 0x408 }, { 0x34, 0x3c, 0x41 },
     { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
     {{ 26, 0 + DIV8 }, { 14, 2 + DIV4 }}
 };

 static struct platinumfb_setting platinum_12 = {
     "800x600x75",
     800, 600, 75, 12,
     0x1010,
     { 832, 1632, 3232 },
     { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
       0, 0x1ce, 0x108, 0x14, 0x20f, 0x27, 0x30, 0x39,
       0x72, 0x202, 0x20e, 0x4e2, 0x4e0, 4, 9, 0x2e,
       0x4de, 0x4df }, { 0x64, 0x6c, 0x71 },
     { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
     {{ 122, 7 + DIV4 }, { 62, 9 + DIV2 }}
 };

 static struct platinumfb_setting platinum_14 = {
     "1024x768x60",
     1024, 768, 60, 14,
     0x10b0,
     { 1056, 2080, 4128 },
     { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
       0, 0x25a, 0x14f, 0x22, 0x29f, 0x43, 0x49, 0x5b,
       0x8e, 0x28e, 0x29e, 0x64c, 0x64a, 0xa, 0xf, 0x44,
       0x644, 0x646 }, { 0x80, 0x88, 0x8d },
     { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
     {{ 71, 6 + DIV2 }, { 118, 13 + DIV2 }}
 };

 static struct platinumfb_setting platinum_20 = {
     "1280x1024x75",
     1280, 1024, 75, 20,
     0x5c00,
     { 1312, 2592, 2592 },
     { 0xffc, 4, 0, 0, 0, 0, 0x428, 0,
       0, 0xb3, 0xd3, 0x12, 0x1a5, 0x23, 0x28, 0x2d,
       0x5e, 0x19e, 0x1a4, 0x854, 0x852, 4, 9, 0x50,
       0x850, 0x851 }, { 0x58, 0x5d, 0x5d },
     { 0, 0xff, 0xff }, { 0x51, 0x55, 0x55 },
     {{ 45, 3 }, { 66, 7 }}
 };

 static struct platinumfb_setting *pfb_setting[] = {
     &platinum_5,
     &platinum_12,
     &platinum_14,
     &platinum_20
 };

 static struct vcons_screen platinumfb_console_screen;

 static int	platinumfb_match(device_t, cfdata_t, void *);
 static void	platinumfb_attach(device_t, device_t, void *);
 static int	platinumfb_init(device_t);
 static int 	platinumfb_set_mode(struct platinumfb_softc *,
 		    const struct videomode *, int);

 CFATTACH_DECL_NEW(platinumfb, sizeof(struct platinumfb_softc),
     platinumfb_match, platinumfb_attach, NULL, NULL);

 struct wsscreen_descr platinumfb_defaultscreen = {
 	"default",
 	0, 0,
 	NULL,
 	8, 16,
 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
 	NULL,
 };

 const struct wsscreen_descr *_platinumfb_scrlist[] = {
 	&platinumfb_defaultscreen,
 	/* XXX other formats, graphics screen? */
 };

 struct wsscreen_list platinumfb_screenlist = {
 	sizeof(_platinumfb_scrlist) / sizeof(struct wsscreen_descr *),
 	_platinumfb_scrlist
 };

 static int	platinumfb_ioctl(void *, void *, u_long, void *, int,
 		    struct lwp *);
 static paddr_t	platinumfb_mmap(void *, void *, off_t, int);
 static void	platinumfb_init_screen(void *, struct vcons_screen *, int,
 			    long *);
 struct wsdisplay_accessops platinumfb_accessops = {
 	platinumfb_ioctl,
 	platinumfb_mmap,
 	NULL,
 	NULL,
 	NULL,
 	NULL,	/* load_font */
 	NULL,	/* polls */
 	NULL,	/* scroll */
 };

 static inline void
 platinumfb_write_reg(struct platinumfb_softc *sc, int reg, uint32_t val)
 {
     out32(sc->sc_reg + PLATINUM_REG_OFFSET_ADDR(reg), val);
 }

 static inline uint32_t
 platinumfb_read_reg(struct platinumfb_softc *sc, int reg)
 {
     return in32(sc->sc_reg + PLATINUM_REG_OFFSET_ADDR(reg));
 }

 static inline void
 platinumfb_write_cmap_reg(struct platinumfb_softc *sc, 
 			  int reg_offset, uint8_t val)
 {
     out8(sc->sc_cmap + reg_offset, val);
 }

 static inline uint8_t
 platinumfb_read_cmap_reg(struct platinumfb_softc *sc, int reg_offset)
 {
     return in8(sc->sc_cmap + reg_offset);
 }

 static inline void
 platinumfb_store_d2(struct platinumfb_softc *sc, 
 			  uint8_t a, uint8_t d)
 {
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, a + 32);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_D2_OFFSET, d);
 }

 static void
 platinumfb_write_cmap(struct platinumfb_softc *sc,
     int reg, uint8_t r, uint8_t g, uint8_t b)
 {
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, reg);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_LUT_OFFSET, r);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_LUT_OFFSET, g);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_LUT_OFFSET, b);
 }

 static uint32_t
 platinumfb_fb_offset_tweak(struct platinumfb_softc *sc)
 {
     char* vmode = sc->sc_pfs->vmode_name;
     uint32_t offset = 0x20;

     if ((strcmp(vmode, "832x624x75") == 0) && (sc->sc_cmode > 0))
 	offset = 0x10;

     return offset;
 }

 /* 2 versions of platinum clock, older one uses clock[1] and
  *     freq = 14.3Mhz * c0 / (c1 & 0x1f) / (1 << (c1 >> 5))
  * newer one uses clock[0] and
  *     freq = 15Mhz * c0 / ((c1 & 0x1f) + 2) / (1 << (c1 >> 5))
  */
 static void
 platinumfb_set_clock(struct platinumfb_softc *sc)
 {
     uint8_t clk_idx = sc->sc_dac_type == PLATINUM_DAC_1 ? 1 : 0;
     uint8_t d2;

     platinumfb_store_d2(sc, 6, 0xc6);

     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, 3+32);
     d2 = platinumfb_read_cmap_reg(sc, PLATINUM_CMAP_D2_OFFSET);

     if (d2 == 2) {
 	platinumfb_store_d2(sc, 7, sc->sc_pfs->clock_params[clk_idx][0]);
 	platinumfb_store_d2(sc, 8, sc->sc_pfs->clock_params[clk_idx][1]);
 	platinumfb_store_d2(sc, 3, 3);
     } else {
 	platinumfb_store_d2(sc, 4, sc->sc_pfs->clock_params[clk_idx][0]);
 	platinumfb_store_d2(sc, 5, sc->sc_pfs->clock_params[clk_idx][1]);
 	platinumfb_store_d2(sc, 3, 2);
     }

     delay(5000);
     platinumfb_store_d2(sc, 9, 0xa6);
 }

 static void
 platinumfb_dac_type(struct platinumfb_softc *sc)
 {
     uint8_t dtype = 0;

     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, 0x40);
     dtype = platinumfb_read_cmap_reg(sc, PLATINUM_CMAP_D2_OFFSET);

     switch (dtype) {
     case PLATINUM_DAC_0:
     case PLATINUM_DAC_1:
 	/* do nothing */
 	break;
     default:
 	aprint_error_dev(sc->sc_dev, "unknown dac 0x%x, using 0x%x\n",
 			 dtype, PLATINUM_DAC_0);
 	dtype = PLATINUM_DAC_0;
 	break;
     }

     /* save type */
     sc->sc_dac_type = dtype;
 }

 static void
 platinumfb_memory_size(struct platinumfb_softc *sc)
 {
     int i;
     uint32_t addr = PLATINUM_FB_BANK_SIZE;
     uint32_t total_vram = PLATINUM_FB_MIN_SIZE;

     uint8_t test_val[] = {0x34, 0x56, 0x78};
     uint8_t bank[] = {0, 0, 0};
     uint8_t num_elems = sizeof(test_val)/sizeof(test_val[0]);

     /* XXX mapiodev needed ? */
     volatile uint8_t *fbuffer = mapiodev((paddr_t)sc->sc_fb, sc->sc_fb_size, false);

     if (fbuffer == NULL)
 	panic("could not mapiodev platinum fb");

     /* turn on all banks of RAM */
     platinumfb_write_reg(sc, 16, (paddr_t)sc->sc_fb);
     platinumfb_write_reg(sc, 20, 0x1011);
     platinumfb_write_reg(sc, 24, 0);

     /*
      * write "unique" value to each bank of memory and read value
      * back. if match assumes VRAM bank exists.  On the powermac 7200,
      * bank0 is always there and soldered to motherboard, don't know
      * if that is the case for others
      */
     for (i = 0 ; i < num_elems; i++) {
 	out8(fbuffer + addr, test_val[i]);
 	out8(fbuffer + addr + 0x8, 0x0);

 	__asm volatile ("eieio; dcbf 0,%0"::"r"(&fbuffer[addr]):"memory"); /* XXX ok? */

 	bank[i] = fbuffer[addr] == test_val[i];
 	total_vram += bank[i] * PLATINUM_FB_BANK_SIZE;
 	addr += PLATINUM_FB_BANK_SIZE;
     }

     if (total_vram >= PLATINUM_FB_MIN_SIZE && total_vram <= PLATINUM_FB_MAX_SIZE) {
 	/* save total vram */
 	sc->sc_vram = total_vram;
     } else {
 	aprint_error_dev(sc->sc_dev,
 			 "invalid VRAM size 0x%x, using min 0x%x\n",
 			 total_vram, PLATINUM_FB_MIN_SIZE);
 	sc->sc_vram = PLATINUM_FB_MIN_SIZE;
     }

     unmapiodev((paddr_t)fbuffer, sc->sc_fb_size);
 }

 static int
 platinumfb_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct confargs *ca = aux;

 	return (strcmp(ca->ca_name, "platinum") == 0);
 }

 static void
 platinumfb_attach(device_t parent, device_t self, void *aux)
 {
 	struct platinumfb_softc *sc = device_private(self);
 	struct confargs *ca = aux;
 	u_int *reg = ca->ca_reg;

 	sc->sc_dev = self;
 	sc->sc_node = ca->ca_node;

 	sc->sc_reg = (uint8_t *)reg[0];
 	sc->sc_reg_size = reg[1];

 	sc->sc_fb = (uint8_t *)reg[2];
 	sc->sc_fb_size = PLATINUM_FB_MAX_SIZE;

 	sc->sc_cmap = (uint8_t *)PLATINUM_CMAP_BASE_ADDR;
 	sc->sc_cmap_size = PLATINUM_CMAP_SIZE;

 	aprint_normal(" reg-addr 0x%08lx fb-addr 0x%08lx cmap-addr 0x%08lx\n",
 		      (paddr_t)sc->sc_reg, 
 		      (paddr_t)sc->sc_fb,
 		      (paddr_t)sc->sc_cmap);

 	config_finalize_register(sc->sc_dev, platinumfb_init);
 }

 static void
 platinumfb_set_cmap(struct platinumfb_softc *sc)
 {
     int i;
     uint8_t tmp;

     switch (sc->sc_cmode) {
     case PLATINUM_CMODE_8:
     default:
 	for (i = 0; i < 256; i++) {
 	    tmp = i & 0xe0;
 	    /*
 	     * replicate bits so 0xe0 maps to a red value of 0xff
 	     * in order to make white look actually white
 	     */
 	    tmp |= (tmp >> 3) | (tmp >> 6);
 	    sc->sc_cmap_red[i] = tmp;

 	    tmp = (i & 0x1c) << 3;
 	    tmp |= (tmp >> 3) | (tmp >> 6);
 	    sc->sc_cmap_green[i] = tmp;

 	    tmp = (i & 0x03) << 6;
 	    tmp |= tmp >> 2;
 	    tmp |= tmp >> 4;
 	    sc->sc_cmap_blue[i] = tmp;

 	    platinumfb_write_cmap(sc, i, sc->sc_cmap_red[i],
 				  sc->sc_cmap_green[i], sc->sc_cmap_blue[i]);
 	}
 	break;
     case PLATINUM_CMODE_16: 
     case PLATINUM_CMODE_32:
 	/* XXX what to do for this, need to write cmap registers ? */
 	for (i = 0; i < 256; i++) {
 	    sc->sc_cmap_red[i] = i;
 	    sc->sc_cmap_green[i] = i;
 	    sc->sc_cmap_blue[i] = i;
 	}
 	break;
     }
 }

 static int
 platinumfb_init(device_t self)
 {
 	struct platinumfb_softc *sc = device_private(self);
 	const struct videomode *mode;
 	struct rasops_info *ri;

 	struct wsemuldisplaydev_attach_args aa;
 	bool console = FALSE;
 	long defattr;
 	int i;

 	/*
 	 * become console if OF variable "output-device" is "screen" or
 	 * contains "platinum", since normal OF video variables are unavailable
 	 */
 	int options;
 	char output_device[128];
 	options = OF_finddevice("/options");
 	if (options == 0 || 
 	    options == -1 ||
 	    OF_getprop(options, "output-device", output_device, sizeof(output_device)) == 0 ) {
 	    aprint_error_dev(sc->sc_dev, "could not get output-device prop, assuming not console\n");
 	}
 	else {
 	    if (strstr(output_device,"platinum") ||
 		strcmp(output_device,"screen") == 0 ) {
 		console = TRUE;
 	    }
 	}	

 	sc->sc_pfs = NULL;

 	/* determine vram memory and dac clock type */
 	platinumfb_memory_size(sc);
 	platinumfb_dac_type(sc);

 	aprint_normal_dev(sc->sc_dev,"console %d dac 0x%x vram 0x%x\n",
 			  console, sc->sc_dac_type, sc->sc_vram);

 	/* XXX */
 	/* mode = pick_mode_by_ref(640, 480, 60); */
 	mode = pick_mode_by_ref(800, 600, 75);
 	/* mode = pick_mode_by_ref(1024, 768, 60); */
 	/* mode = pick_mode_by_ref(1280, 1024, 75); */
 	if (mode == NULL) {
 	    aprint_error_dev(sc->sc_dev, "pick_mode_by_ref failed\n");
 	    return 0;
 	}

 	if (
 	    /* XXX */
 	    /* platinumfb_set_mode(sc, mode, 32) != 0 */
 	    /* platinumfb_set_mode(sc, mode, 16) != 0 */
 	    platinumfb_set_mode(sc, mode, 8) != 0
 	    )	
 	{
 	    aprint_error_dev(sc->sc_dev, "platinumfb_set_mode failed\n");
 	    return 0;
 	}

 	vcons_init(&sc->vd, sc, &platinumfb_defaultscreen,
 		   &platinumfb_accessops);
 	sc->vd.init_screen = platinumfb_init_screen;

 	ri = &platinumfb_console_screen.scr_ri;
 	vcons_init_screen(&sc->vd, &platinumfb_console_screen, 1, &defattr);

 	switch(sc->sc_cmode) {
 	case PLATINUM_CMODE_8:
 	default:
 	    memset(sc->sc_fb,
 		   (uint8_t)(ri->ri_devcmap[(defattr >> 16) & 0xf] & 0xff),
 		   sc->sc_width * sc->sc_linebytes);
 	    break;
 	case PLATINUM_CMODE_16:
 	    for (i = 0 ; i < sc->sc_vram ; i+=2)
 		*(uint16_t *)(sc->sc_fb + i) = 
 		    (uint16_t)(ri->ri_devcmap[(defattr >> 16) & 0xf] & 0xffff);
 	    break;
 	case PLATINUM_CMODE_32:
 	    for (i = 0 ; i < sc->sc_vram ; i+=4)
 		*(uint32_t *)(sc->sc_fb + i) = 
 		    (uint32_t)(ri->ri_devcmap[(defattr >> 16) & 0xf]);
 	    break;
 	}

 	platinumfb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;

 	platinumfb_defaultscreen.textops = &ri->ri_ops;
 	platinumfb_defaultscreen.capabilities = ri->ri_caps;
 	platinumfb_defaultscreen.nrows = ri->ri_rows;
 	platinumfb_defaultscreen.ncols = ri->ri_cols;

 	if (console) {
 		wsdisplay_cnattach(&platinumfb_defaultscreen, ri, 0, 0,
 		    defattr);
 		vcons_replay_msgbuf(&platinumfb_console_screen);
 	}

 	aa.console = console;
 	aa.scrdata = &platinumfb_screenlist;
 	aa.accessops = &platinumfb_accessops;
 	aa.accesscookie = &sc->vd;

 	config_found(self, &aa, wsemuldisplaydevprint);

 	return 0;
 }

 static int
 platinumfb_set_mode(struct platinumfb_softc *sc,
     const struct videomode *mode, int depth)
 {
         int i;
 	bool one_bank;

 	/* determine depth settings */
 	switch (depth) {
 	case 8:
 	    sc->sc_cmode = PLATINUM_CMODE_8;
 	    sc->sc_depth = 8;
 	    break;
 	case 15:
 	case 16:
 	    sc->sc_cmode = PLATINUM_CMODE_16;
 	    sc->sc_depth = 15; /* XXX or 16 ? */
 	    break;
 	case 24:
 	case 32:
 	    sc->sc_cmode = PLATINUM_CMODE_32;
 	    sc->sc_depth = 32; /* XXX or 24? */
 	    break;
 	default:
 	    aprint_error_dev(sc->sc_dev, "unknown depth [%d] using 8\n", depth);
 	    sc->sc_cmode = PLATINUM_CMODE_8;
 	    sc->sc_depth = 8;
 	    break;
 	}

 	/* first find the parameter for the mode register */
 	i = 0;
 	while((i < __arraycount(pfb_setting)) &&
 	      (strcmp(mode->name, pfb_setting[i]->vmode_name) != 0))
 	    i++;

 	if (i >= __arraycount(pfb_setting)) {
 		aprint_error_dev(sc->sc_dev,
 		    "Can't find a mode register value for %s\n", 
 				 mode->name);
 		return EINVAL;
 	} 

 	/* check if we have enough video memory */
 	if ((mode->hdisplay * mode->vdisplay * (depth >> 3) + pfb_setting[i]->fb_offset) > 
 	    sc->sc_vram) {
 	    aprint_error_dev(sc->sc_dev, "Not enough video RAM for %s\n",
 			     mode->name);
 	    return EINVAL;
 	}

 	/* found a mode */
 	sc->sc_pfs = pfb_setting[i];

 	platinumfb_set_cmap(sc);

 	one_bank = sc->sc_vram == PLATINUM_FB_BANK_SIZE;

 	/* now start programming the chip */
 	platinumfb_write_reg(sc, 24, 7);    /* turn off display */

 	for (i = 0; i < 26; ++i)
 	    platinumfb_write_reg(sc, i+32, sc->sc_pfs->regs[i]);

 	platinumfb_write_reg(sc, 26+32, one_bank ? sc->sc_pfs->offset[sc->sc_cmode] + 4 - sc->sc_cmode :
 			                           sc->sc_pfs->offset[sc->sc_cmode]);

 	platinumfb_write_reg(sc, 16, (uint32_t)sc->sc_fb + sc->sc_pfs->fb_offset + 0x10);
 	platinumfb_write_reg(sc, 18, sc->sc_pfs->pitch[sc->sc_cmode]);
 	platinumfb_write_reg(sc, 19, one_bank ? sc->sc_pfs->mode[sc->sc_cmode+1] :
 			                        sc->sc_pfs->mode[sc->sc_cmode]);

 	platinumfb_write_reg(sc, 20, one_bank ? 0x11 : 0x1011);
 	platinumfb_write_reg(sc, 21, 0x100);
 	platinumfb_write_reg(sc, 22, 1);
 	platinumfb_write_reg(sc, 23, 1);
 	platinumfb_write_reg(sc, 26, 0xc00);
 	platinumfb_write_reg(sc, 27, 0x235);
 	/* platinumfb_write_reg(sc, 27, 0x2aa); */

 	platinumfb_store_d2(sc, 0, one_bank ? sc->sc_pfs->dacula_ctrl[sc->sc_cmode] & 0xf :
 			                      sc->sc_pfs->dacula_ctrl[sc->sc_cmode]);
 	platinumfb_store_d2(sc, 1, 4);
 	platinumfb_store_d2(sc, 2, 0);

 	platinumfb_set_clock(sc);

 	platinumfb_write_reg(sc, 24, 0);  /* turn display on */

 	sc->sc_modereg = sc->sc_pfs->macmode;
 	sc->sc_videomode = mode;
 	sc->sc_width = mode->hdisplay;
 	sc->sc_height = mode->vdisplay;
 	sc->sc_linebytes = mode->hdisplay * (1 << sc->sc_cmode) + platinumfb_fb_offset_tweak(sc);

 	aprint_normal_dev(sc->sc_dev, "switched to %s in %d bit color\n",
 			  sc->sc_pfs->vmode_name, sc->sc_depth);
 	return 0;
 }

 static int
 platinumfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
 	struct lwp *l)
 {
 	struct vcons_data *vd = v;
 	struct platinumfb_softc *sc = vd->cookie;
 	struct wsdisplay_fbinfo *wdf;
 	struct vcons_screen *ms = vd->active;

 	switch (cmd) {
 	case WSDISPLAYIO_GTYPE:
 		*(u_int *)data = WSDISPLAY_TYPE_PLATINUM;
 		return 0;

 	case WSDISPLAYIO_GINFO:
 		wdf = (void *)data;
 		wdf->height = ms->scr_ri.ri_height;
 		wdf->width = ms->scr_ri.ri_width;
 		wdf->depth = ms->scr_ri.ri_depth;
 		wdf->cmsize = 256;
 		return 0;

 	case WSDISPLAYIO_GET_FBINFO: {
 	    struct wsdisplayio_fbinfo *fbi = data;
 	    return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
 	}

 	case WSDISPLAYIO_LINEBYTES:
 	        *(u_int *)data = sc->sc_linebytes;
 		return 0;

 	case WSDISPLAYIO_SMODE: {
 		int new_mode = *(int*)data;
 		if (new_mode != sc->sc_mode) {
 			sc->sc_mode = new_mode;
 			if (new_mode == WSDISPLAYIO_MODE_EMUL) {
 				vcons_redraw_screen(ms);
 			}
 		}
 		}
 		return 0;
 	}
 	return EPASSTHROUGH;
 }

 static paddr_t
 platinumfb_mmap(void *v, void *vs, off_t offset, int prot)
 {
 	struct vcons_data *vd = v;
 	struct platinumfb_softc *sc = vd->cookie;
 	off_t fb_offset = sc->sc_pfs->fb_offset;
 	paddr_t pa = -1;

 	/* XXX need to worry about superuser, or mapping other registers? */

 	/* regular framebuffer mmap()ing */
 	if (offset >= 0 && 
 	    (offset < (sc->sc_vram - fb_offset - platinumfb_fb_offset_tweak(sc))))
 	{
 	    pa = (paddr_t)(sc->sc_fb + fb_offset + offset);
 	}

 	return pa;
 }

 static void
 platinumfb_init_screen(void *cookie, struct vcons_screen *scr,
     int existing, long *defattr)
 {
 	struct platinumfb_softc *sc = cookie;
 	struct rasops_info *ri = &scr->scr_ri;

 	memset(ri, 0, sizeof(struct rasops_info));
 	ri->ri_depth = sc->sc_depth;
 	ri->ri_width = sc->sc_width;
 	ri->ri_height = sc->sc_height;
 	ri->ri_stride = sc->sc_linebytes;
 	ri->ri_bits = sc->sc_fb + sc->sc_pfs->fb_offset + platinumfb_fb_offset_tweak(sc);
 	ri->ri_flg = RI_CENTER;

 	switch (sc->sc_cmode) {
 	case PLATINUM_CMODE_8:
 	default:
 	    /* 640x480x60 800x600x75 1024x768x60 1280x1024x75 worked */
 	    ri->ri_flg |= RI_ENABLE_ALPHA | RI_8BIT_IS_RGB;
 	    break;
 	case PLATINUM_CMODE_16:
 	    /* XXX stamp[] in rasops*.c may need bytes swapped somehow */
 	    /* ri->ri_flg |= RI_BSWAP; */

 	    /* 1024x768x60 didn't work with this flag,
 	       not enough vram to test 1280x1024x75 */
 	    if ( strcmp(sc->sc_pfs->vmode_name,"640x480x60") == 0 ||
 		 strcmp(sc->sc_pfs->vmode_name,"800x600x75") == 0 )
 		ri->ri_flg |= RI_ENABLE_ALPHA;

 	    break;
 	case PLATINUM_CMODE_32:
 	    /* XXX stamp[] in rasops*.c may need bytes swapped somehow */
 	    /*ri->ri_flg |= RI_BSWAP; */

 	    /* 640x480x60 800x600x75 worked with this flag,
 	       not enough vram to test others */
 	    if ( strcmp(sc->sc_pfs->vmode_name,"640x480x60") == 0 ||
 		 strcmp(sc->sc_pfs->vmode_name,"800x600x75") == 0 )
 		ri->ri_flg |= RI_ENABLE_ALPHA;

 	    break;
 	}

 	scr->scr_flags |= VCONS_DONT_READ;

 	rasops_init(ri, 0, 0);
 	ri->ri_caps = WSSCREEN_WSCOLORS;

 	rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
 		    sc->sc_width / ri->ri_font->fontwidth);

 	ri->ri_hw = scr;

 	/* XXX override colormap for 16 & 32 bit, which seems to be CMY, but 8 bit is RGB?? */
 	if (ri->ri_depth >= 24)	{
 	    /* 32 bit no swap */
 	    /* XXX sometimes works, sometimes background looks yellow */
 	    ri->ri_devcmap[0] = 0x007f7f7f; // black
 	    ri->ri_devcmap[1] = 0x00007f7f; // red
 	    ri->ri_devcmap[2] = 0x007f007f; // green
 	    ri->ri_devcmap[3] = 0x0000007f; // yellow
 	    ri->ri_devcmap[4] = 0x007f7f00; // blue
 	    ri->ri_devcmap[5] = 0x00007f00; // magenta
 	    ri->ri_devcmap[6] = 0x007f0000; // cyan
 	    ri->ri_devcmap[7] = 0x00000000; // grey/white

 	    ri->ri_devcmap[8] = 0x00ffffff; // black
 	    ri->ri_devcmap[9] = 0x0000ffff; // red
 	    ri->ri_devcmap[10] = 0x00ff00ff; // green
 	    ri->ri_devcmap[11] = 0x000000ff; // yellow
 	    ri->ri_devcmap[12] = 0x00ffff00; // blue
 	    ri->ri_devcmap[13] = 0x0000ff00; // magenta
 	    ri->ri_devcmap[14] = 0x00ff0000; // cyan
 	    ri->ri_devcmap[15] = 0x00000000; // white
 	} 
 	else if (ri->ri_depth >= 15)	{
 	    /* 15 bit no swap */
 	    /* XXX don't understand how to get a good black or why white is 0x0003 */
 	    ri->ri_devcmap[0] = 0x3def3def; // black
 	    ri->ri_devcmap[1] = 0x01ef01ef; // red
 	    ri->ri_devcmap[2] = 0x3c0f3c0f; // green
 	    ri->ri_devcmap[3] = 0x000f000f; // yellow
 	    ri->ri_devcmap[4] = 0x3de03de0; // blue
 	    ri->ri_devcmap[5] = 0x01e001e0; // magenta
 	    ri->ri_devcmap[6] = 0x3c003c00; // cyan
 	    ri->ri_devcmap[7] = 0x00020002; // grey/white

 	    ri->ri_devcmap[8]  = 0x7fff7fff; // black
 	    ri->ri_devcmap[9]  = 0x03ff03ff; // red
 	    ri->ri_devcmap[10] = 0x7c1f7c1f; // green
 	    ri->ri_devcmap[11] = 0x001f001f; // yellow
 	    ri->ri_devcmap[12] = 0x7fe07fe0; // blue
 	    ri->ri_devcmap[13] = 0x03e003e0; // magenta
 	    ri->ri_devcmap[14] = 0x7c007c00; // cyan
 	    ri->ri_devcmap[15] = 0x00030003; // white
 	}

 }
 ===================================================================
 ==== new file
 sys/arch/macppc/dev/platinumfbreg.h
 ===================================================================
 /*
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */

 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: platinumfbreg.h,v 1.1 2014/10/31 12:00:00 macallan Exp $");

 #ifndef PLATINUMFBREG_H
 #define PLATINUMFBREG_H

 /*
  * platinum register address offsets.
  * registers are each 32 bits with 12*8bits of padding,
  * 128 registers total
  */
 #define PLATINUM_REG_OFFSET_ADDR(x) (x * 0x10)
 #define PLATINUM_REG_COUNT          128

 /*
  * colormap register addresses.
  * registers are each 8 bits with 15*8 bits of padding
  */
 #define PLATINUM_CMAP_BASE_ADDR   0xf301b000 /* XXX not in ofw ? */
 #define PLATINUM_CMAP_ADDR_OFFSET 0x00000000
 #define PLATINUM_CMAP_D1_OFFSET   0x00000010
 #define PLATINUM_CMAP_D2_OFFSET   0x00000020
 #define PLATINUM_CMAP_LUT_OFFSET  0x00000030
 #define PLATINUM_CMAP_SIZE        0x1000     /* XXX ofw says 0x800? */

 /* framebuffer */
 #define PLATINUM_FB_BANK_SIZE 0x100000
 #define PLATINUM_FB_MIN_SIZE (1 * PLATINUM_FB_BANK_SIZE)
 #define PLATINUM_FB_MAX_SIZE (4 * PLATINUM_FB_BANK_SIZE)

 /* depth/colormodes */
 #define PLATINUM_CMODE_8  0
 #define PLATINUM_CMODE_16 1
 #define PLATINUM_CMODE_32 2

 /* DACula types */
 #define PLATINUM_DAC_0 0x84
 #define PLATINUM_DAC_1 0x3c

 #endif /* PLATINUMFBREG_H */

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Thu, 30 Oct 2014 19:49:30 -0400

 Just a minor status update, I modified the voyagerfb_putcmap/getcmap
 for platinum.  X (startx) runs with 8 16 and 32 bpp (not 15). 16 & 32
 bpp still have wrong colormaps.  I used xsrc built on 10/28/14 with
 -mcpu=601 flag.

 When X is running, the screen (in 8 16 32 bpp) appears to have the
 wrong screen offset.  The screen looks like it is shifted so normal
 left edge of framebuffer is almost at right edge of monitor.

 Virtual console switching doesn't work when X running, not sure if it
 is supposed to or not.

 In normal console mode, I noticed some console text showed up in
 another virtual console with "colorbars".

 One thing I was looking at is the framebuffer offset changes depending
 on the video mode, so I probably missed something with that.

 Thanks

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Fri, 21 Nov 2014 10:44:53 -0500

 After a lot of trial and error, I have some fixes to get console and
 X/wsfb working for 8/16/32 bpp and various resolutions. Virtual
 terminal switching also works (though I'm not responsible for that).

 1) Update WSDISPLAY_TYPE_PLATINUM number to last in wsconsio.h list,
 diff attached.

 2) Changes in sys/arch/macppc/dev/platinumfb.c.  Whole file is
 attached below.

 3) "options RASOPS_SMALL" can be removed from kernel, and diff for
 rasops15.c used below.  I made a fix (hopefully) with stamp and
 endianess attached below which repaired 15 bit console output.

 Some other issue still remain

 - Right-Shift, Right-Option, Right-Command weren't working for me in
 X.  I have apple adb keyboard but haven't looked into this yet

 - Still need to test X with a mouse as I don't have one (yet) that
 works on my machine.  I should be getting an adb one soon to try.

 - I made various attempts to switch from 8bpp console to 16bpp X/wsfb
 but I couldn't get it to work.  The wsfb man page seems to indicate
 changing resolutions or depths isn't supported.  My work-around was
 to add
 	#define PLATINUM_FB_DEPTH 16
 	#define PLATINUM_FB_VMODE "800x600x75"

 at top of platinumfb.c.


 Index: sys/dev/wscons/wsconsio.h
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/wscons/wsconsio.h,v
 retrieving revision 1.109
 diff -b -u -r1.109 wsconsio.h
 --- sys/dev/wscons/wsconsio.h	9 Nov 2014 14:33:21 -0000	1.109
 +++ sys/dev/wscons/wsconsio.h	21 Nov 2014 15:01:48 -0000
 @@ -335,6 +335,8 @@
  #define WSDISPLAY_TYPE_WINDERMERE 58	/* SoC for EPOC32 Series 5mx */
  #define WSDISPLAY_TYPE_CLPS711X	59	/* CL PS-711x  */
  #define WSDISPLAY_TYPE_ALLWINNER 60	/* Allwinner ARM SoC */
 +#define WSDISPLAY_TYPE_PLATINUM	61	/* Apple onboard video 'platinum' */
 +

  /* Basic display information.  Not applicable to all display types. */
  struct wsdisplay_fbinfo {
 Index: sys/dev/rasops/rasops15.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/rasops/rasops15.c,v
 retrieving revision 1.20
 diff -b -u -r1.20 rasops15.c
 --- sys/dev/rasops/rasops15.c	17 Apr 2012 12:06:25 -0000	1.20
 +++ sys/dev/rasops/rasops15.c	21 Nov 2014 15:01:50 -0000
 @@ -217,17 +217,26 @@
  	bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffff;
  	stamp_attr = attr;

 +	/*
 +	 * XXX - someone should sanity check but think this was doing
 +	 *   stamp[i] = 8|16, stamp[i+1] = 2|4 (little endian)
 +	 *   stamp[i] = 4|2, stamp[i+1] = 16|8 (big endian)
 +	 * where should be
 +	 *   stamp[i] = 2|4, stamp[i+1] = 8|16 (little endian)
 +	 *   stamp[i] = 16|8, stamp[i+1] = 4|2 (big endian)
 +	 */
  	for (i = 0; i < 32; i += 2) {
  #if BYTE_ORDER == LITTLE_ENDIAN
 -		stamp[i] = (i & 16 ? fg : bg);
 -		stamp[i] |= ((i & 8 ? fg : bg) << 16);
 -		stamp[i + 1] = (i & 4 ? fg : bg);
 -		stamp[i + 1] |= ((i & 2 ? fg : bg) << 16);
 +            stamp[i] = (i & 4 ? fg : bg);
 +            stamp[i] |= ((i & 2 ? fg : bg) << 16);
 +            stamp[i + 1] = (i & 16 ? fg : bg);
 +            stamp[i + 1] |= ((i & 8 ? fg : bg) << 16);
 +
  #else
 -		stamp[i] = (i & 2 ? fg : bg);
 -		stamp[i] |= ((i & 4 ? fg : bg) << 16);
 -		stamp[i + 1] = (i & 8 ? fg : bg);
 -		stamp[i + 1] |= ((i & 16 ? fg : bg) << 16);
 +            stamp[i] = (i & 8 ? fg : bg);
 +            stamp[i] |= ((i & 16 ? fg : bg) << 16);
 +            stamp[i + 1] = (i & 2 ? fg : bg);
 +            stamp[i + 1] |= ((i & 4 ? fg : bg) << 16);
  #endif
  	}
  }
 ===================================================================
 ==== new file
 sys/arch/macppc/dev/platinumfb.c
 ===================================================================
 /*
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */

 /* A console driver for Apple's Platinum onboard video controller,
  * found in (all?) Catalyst logic boards including the Powermac 7200.
  *
  * Used valkyriefb.c from NetBSD, and platinumfb.c/platinumfb.h from
  * Linux sources as templates.
  *
  * Platinum is broken regarding openfirmware video variables.  In OF,
  * for a powermac 7200, doing "dev /platinum .properties" results in:
  *
  *	name                    platinum
  *	device_type             display
  *	model                   AAPL,343S1184
  *	AAPL,connector          monitor
  *	reg                     F8000000  00000800
  *	                        F1000000  01000000
  *	AAPL,interrupts         0000001E
  *
  * The first reg is the register set, and the second is for the
  * framebuffer.  There is also a set of colormap registers hardcoded
  * in platinumfbreg.h that (I think) aren't in openfirmware.
  *
  * powermac 7200 VRAM min and max limits are 1 and 4 Mb respectively.
  * OF claims 16M so we don't use that value.  If other machines can
  * can have more or less VRAM this code will need to be modified
  */

 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: platinumfb.c,v 1.1 2014/10/31 12:00:00 macallan Exp $");

 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/device.h>

 #include <uvm/uvm_param.h>

 #include <dev/ofw/openfirm.h>

 #include <machine/autoconf.h>
 #include <machine/pio.h>

 #include <dev/wscons/wsdisplayvar.h>
 #include <dev/wscons/wsconsio.h>
 #include <dev/wsfont/wsfont.h>
 #include <dev/rasops/rasops.h>
 #include <dev/wscons/wsdisplay_vconsvar.h>

 #include <dev/videomode/videomode.h>

 #include <arch/macppc/dev/platinumfbreg.h>

 #include <sys/sysctl.h>

 #include "opt_wsemul.h"

 /* console and X bpp/depth,  8 or 16 or 32 */
 #define PLATINUM_FB_DEPTH 16

 /* resolution, from one of platinumfb_setting vmode_name's */
 #define PLATINUM_FB_VMODE "800x600x75"

 struct platinumfb_setting {
         char vmode_name[24];
 	int32_t width;
 	int32_t height;
     	uint8_t freq;
 	uint8_t macmode;

 	int32_t	pitch[3];
 	uint32_t regs[26];
 	uint8_t offset[3];
 	uint8_t mode[3];
 	uint8_t dacula_ctrl[3];
 	uint8_t clock_params[2][2];
 };

 struct platinumfb_softc {
 	device_t sc_dev;
 	int sc_node;

         uint8_t *sc_reg;
 	uint32_t sc_reg_size;

     	uint8_t *sc_cmap;
 	uint32_t sc_cmap_size;

 	uint8_t *sc_fb;
 	uint32_t sc_fb_size;

 	int sc_depth;
 	int sc_width, sc_height, sc_linebytes;
 	const struct videomode *sc_videomode;
 	uint8_t sc_modereg;

         int sc_mode;

 	u_char sc_cmap_red[256];
 	u_char sc_cmap_green[256];
 	u_char sc_cmap_blue[256];

 	struct vcons_data vd;

         uint8_t sc_cmode;
         uint8_t sc_dac_type;
         uint32_t sc_vram;
         int sc_on;
         struct platinumfb_setting *sc_pfs;
 };

 #define DIV2	0x20
 #define DIV4	0x40
 #define DIV8	0x60
 #define DIV16	0x80

 static struct platinumfb_setting platinum_5 = {
     "640x480x60",
     640, 480, 60, 5,
     { 672, 1312, 2592 },
     { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
       0, 0x15e, 0xc8, 0x18, 0x18f, 0x2f, 0x35, 0x3e,
       0x42, 0x182, 0x18e, 0x41a, 0x418, 2, 7, 0x44,
       0x404, 0x408 }, { 0x34, 0x3c, 0x41 },
     { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
     {{ 26, 0 + DIV8 }, { 14, 2 + DIV4 }}
 };

 static struct platinumfb_setting platinum_12 = {
     "800x600x75",
     800, 600, 75, 12,
     { 832, 1632, 3232 },
     { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
       0, 0x1ce, 0x108, 0x14, 0x20f, 0x27, 0x30, 0x39,
       0x72, 0x202, 0x20e, 0x4e2, 0x4e0, 4, 9, 0x2e,
       0x4de, 0x4df }, { 0x64, 0x6c, 0x71 },
     { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
     {{ 122, 7 + DIV4 }, { 62, 9 + DIV2 }}
 };

 static struct platinumfb_setting platinum_14 = {
     "1024x768x60",
     1024, 768, 60, 14,
     { 1056, 2080, 4128 },
     { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
       0, 0x25a, 0x14f, 0x22, 0x29f, 0x43, 0x49, 0x5b,
       0x8e, 0x28e, 0x29e, 0x64c, 0x64a, 0xa, 0xf, 0x44,
       0x644, 0x646 }, { 0x80, 0x88, 0x8d },
     { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
     {{ 71, 6 + DIV2 }, { 118, 13 + DIV2 }}
 };

 static struct platinumfb_setting platinum_20 = {
     "1280x1024x75",
     1280, 1024, 75, 20,
     { 1312, 2592, 2592 },
     { 0xffc, 4, 0, 0, 0, 0, 0x428, 0,
       0, 0xb3, 0xd3, 0x12, 0x1a5, 0x23, 0x28, 0x2d,
       0x5e, 0x19e, 0x1a4, 0x854, 0x852, 4, 9, 0x50,
       0x850, 0x851 }, { 0x58, 0x5d, 0x5d },
     { 0, 0xff, 0xff }, { 0x51, 0x55, 0x55 },
     {{ 45, 3 }, { 66, 7 }}
 };

 static struct platinumfb_setting *pfb_setting[] = {
     &platinum_5,
     &platinum_12,
     &platinum_14,
     &platinum_20
 };

 static struct vcons_screen platinumfb_console_screen;

 static int	platinumfb_match(device_t, cfdata_t, void *);
 static void	platinumfb_attach(device_t, device_t, void *);

 CFATTACH_DECL_NEW(platinumfb, sizeof(struct platinumfb_softc),
     platinumfb_match, platinumfb_attach, NULL, NULL);

 static int	platinumfb_init(device_t);
 static int 	platinumfb_set_mode(struct platinumfb_softc *,
 				    const struct videomode *, int);
 static int	platinumfb_ioctl(void *, void *, u_long, void *, int,
 				 struct lwp *);
 static paddr_t	platinumfb_mmap(void *, void *, off_t, int);
 static void	platinumfb_init_screen(void *, struct vcons_screen *, int,
 				       long *);
 static int	platinumfb_putcmap(struct platinumfb_softc *,
 				   struct wsdisplay_cmap *);
 static int 	platinumfb_getcmap(struct platinumfb_softc *,
 				   struct wsdisplay_cmap *);
 static void	platinumfb_init_cmap(struct platinumfb_softc *);
 static void	platinumfb_restore_palette(struct platinumfb_softc *);
 static void	platinumfb_putpalreg(struct platinumfb_softc *,
 				     uint8_t, uint8_t, uint8_t, uint8_t);
 static uint32_t platinumfb_line_tweak(struct platinumfb_softc *);
 static paddr_t	platinumfb_page_align_up(struct platinumfb_softc *);
 static void 	platinumfb_set_clock(struct platinumfb_softc *);
 static void	platinumfb_dac_type(struct platinumfb_softc *);
 static void	platinumfb_memory_size(struct platinumfb_softc *);
 static void	platinumfb_set_hardware(struct platinumfb_softc *);

 static inline void platinumfb_write_reg(struct platinumfb_softc *,
 					int, uint32_t);
 static inline uint32_t platinumfb_read_reg(struct platinumfb_softc *, int);
 static inline void platinumfb_write_cmap_reg(struct platinumfb_softc *, 
 					     int, uint8_t);
 static inline uint8_t platinumfb_read_cmap_reg(struct platinumfb_softc *, int);
 static inline void platinumfb_store_d2(struct platinumfb_softc *, 
 				       uint8_t, uint8_t);

 struct wsscreen_descr platinumfb_defaultscreen = {
 	"default",
 	0, 0,
 	NULL,
 	8, 16,
 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
 	NULL,
 };

 const struct wsscreen_descr *_platinumfb_scrlist[] = {
 	&platinumfb_defaultscreen,
 	/* XXX other formats, graphics screen? */
 };

 struct wsscreen_list platinumfb_screenlist = {
 	sizeof(_platinumfb_scrlist) / sizeof(struct wsscreen_descr *),
 	_platinumfb_scrlist
 };

 struct wsdisplay_accessops platinumfb_accessops = {
 	platinumfb_ioctl,
 	platinumfb_mmap,
 	NULL,
 	NULL,
 	NULL,
 	NULL,	/* load_font */
 	NULL,	/* polls */
 	NULL,	/* scroll */
 };

 static inline void
 platinumfb_write_reg(struct platinumfb_softc *sc, int reg, uint32_t val)
 {
     out32(sc->sc_reg + PLATINUM_REG_OFFSET_ADDR(reg), val);
 }

 static inline uint32_t
 platinumfb_read_reg(struct platinumfb_softc *sc, int reg)
 {
     return in32(sc->sc_reg + PLATINUM_REG_OFFSET_ADDR(reg));
 }

 static inline void
 platinumfb_write_cmap_reg(struct platinumfb_softc *sc, 
 			  int reg_offset, uint8_t val)
 {
     out8(sc->sc_cmap + reg_offset, val);
 }

 static inline uint8_t
 platinumfb_read_cmap_reg(struct platinumfb_softc *sc, int reg_offset)
 {
     return in8(sc->sc_cmap + reg_offset);
 }

 static inline void
 platinumfb_store_d2(struct platinumfb_softc *sc, 
 			  uint8_t a, uint8_t d)
 {
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, a + 32);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_D2_OFFSET, d);
 }

 static void
 platinumfb_putpalreg(struct platinumfb_softc *sc,
     uint8_t reg, uint8_t r, uint8_t g, uint8_t b)
 {
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, reg);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_LUT_OFFSET, r);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_LUT_OFFSET, g);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_LUT_OFFSET, b);
 }

 static uint32_t
 platinumfb_line_tweak(struct platinumfb_softc *sc)
 {
     /* bytes per line adjustment depending on resolution and depth */
     if (sc->sc_cmode > PLATINUM_CMODE_8 &&
 	strcmp(sc->sc_pfs->vmode_name, "832x624x75") == 0)
 	return 0x10;
     else
 	return 0x20;
 }

 static paddr_t
 platinumfb_page_align_up(struct platinumfb_softc *sc)
 {
     /* round up framebuffer address to the next highest page */
     paddr_t addr = (paddr_t)sc->sc_fb;
     paddr_t ret = round_page(addr);

     if (ret == addr)
 	ret = round_page(addr + 1);

     return ret;
 }

 /* 2 versions of platinum clock, older one uses clock[1] and
  *     freq = 14.3Mhz * c0 / (c1 & 0x1f) / (1 << (c1 >> 5))
  * newer one uses clock[0] and
  *     freq = 15Mhz * c0 / ((c1 & 0x1f) + 2) / (1 << (c1 >> 5))
  */
 static void
 platinumfb_set_clock(struct platinumfb_softc *sc)
 {
     uint8_t clk_idx = sc->sc_dac_type == PLATINUM_DAC_1 ? 1 : 0;
     uint8_t d2;

     platinumfb_store_d2(sc, 6, 0xc6);

     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, 3+32);
     d2 = platinumfb_read_cmap_reg(sc, PLATINUM_CMAP_D2_OFFSET);

     if (d2 == 2) {
 	platinumfb_store_d2(sc, 7, sc->sc_pfs->clock_params[clk_idx][0]);
 	platinumfb_store_d2(sc, 8, sc->sc_pfs->clock_params[clk_idx][1]);
 	platinumfb_store_d2(sc, 3, 3);
     } else {
 	platinumfb_store_d2(sc, 4, sc->sc_pfs->clock_params[clk_idx][0]);
 	platinumfb_store_d2(sc, 5, sc->sc_pfs->clock_params[clk_idx][1]);
 	platinumfb_store_d2(sc, 3, 2);
     }

     delay(5000);
     platinumfb_store_d2(sc, 9, 0xa6);
 }

 static void
 platinumfb_dac_type(struct platinumfb_softc *sc)
 {
     uint8_t dtype = 0;

     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, 0x40);
     dtype = platinumfb_read_cmap_reg(sc, PLATINUM_CMAP_D2_OFFSET);

     switch (dtype) {
     case PLATINUM_DAC_0:
     case PLATINUM_DAC_1:
 	/* do nothing */
 	break;
     default:
 	aprint_error_dev(sc->sc_dev, "unknown dac 0x%x, using 0x%x\n",
 			 dtype, PLATINUM_DAC_0);
 	dtype = PLATINUM_DAC_0;
 	break;
     }

     /* save type */
     sc->sc_dac_type = dtype;
 }

 static void
 platinumfb_memory_size(struct platinumfb_softc *sc)
 {
     int i;
     off_t offset = PLATINUM_FB_BANK_SIZE;
     paddr_t total_vram = PLATINUM_FB_MIN_SIZE;

     uint8_t test_val[] = {0x34, 0x56, 0x78};
     uint8_t bank[] = {0, 0, 0};
     uint8_t num_elems = sizeof(test_val)/sizeof(test_val[0]);

     volatile uint8_t *fbuffer = mapiodev((paddr_t)sc->sc_fb, sc->sc_fb_size, false);

     if (fbuffer == NULL)
 	panic("platinumfb could not mapiodev");

     /* turn on all banks of RAM */
     platinumfb_write_reg(sc, 16, (paddr_t)sc->sc_fb);
     platinumfb_write_reg(sc, 20, 0x1011);
     platinumfb_write_reg(sc, 24, 0);

     /*
      * write "unique" value to each bank of memory and read value
      * back. if match assumes VRAM bank exists.  On the powermac 7200,
      * bank0 is always there and soldered to motherboard, don't know
      * if that is the case for others
      */
     for (i = 0 ; i < num_elems; i++) {
 	out8(fbuffer + offset, test_val[i]);
 	out8(fbuffer + offset + 0x8, 0x0);

 	__asm volatile ("eieio; dcbf 0,%0"::"r"(&fbuffer[offset]):"memory");

 	bank[i] = fbuffer[offset] == test_val[i];
 	total_vram += bank[i] * PLATINUM_FB_BANK_SIZE;
 	offset += PLATINUM_FB_BANK_SIZE;
     }

     /* save total vram or minimum */
     if (total_vram >= PLATINUM_FB_MIN_SIZE && total_vram <= PLATINUM_FB_MAX_SIZE) {
 	sc->sc_vram = total_vram;
     } else {
 	aprint_error_dev(sc->sc_dev,
 			 "invalid VRAM size 0x%lx, using min 0x%x\n",
 			 total_vram, PLATINUM_FB_MIN_SIZE);
 	sc->sc_vram = PLATINUM_FB_MIN_SIZE;
     }

     unmapiodev((paddr_t)fbuffer, sc->sc_fb_size);
 }

 static int
 platinumfb_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct confargs *ca = aux;

 	return (strcmp(ca->ca_name, "platinum") == 0);
 }

 static void
 platinumfb_attach(device_t parent, device_t self, void *aux)
 {
 	struct platinumfb_softc *sc = device_private(self);
 	struct confargs *ca = aux;
 	u_int *reg = ca->ca_reg;

 	sc->sc_dev = self;
 	sc->sc_node = ca->ca_node;

 	sc->sc_reg = (uint8_t *)reg[0];
 	sc->sc_reg_size = reg[1];

 	sc->sc_fb = (uint8_t *)reg[2];
 	sc->sc_fb_size = PLATINUM_FB_MAX_SIZE;

 	sc->sc_cmap = (uint8_t *)PLATINUM_CMAP_BASE_ADDR;
 	sc->sc_cmap_size = PLATINUM_CMAP_SIZE;

 	aprint_normal(" reg-addr 0x%08lx fb-addr 0x%08lx cmap-addr 0x%08lx\n",
 		      (paddr_t)sc->sc_reg, 
 		      (paddr_t)sc->sc_fb,
 		      (paddr_t)sc->sc_cmap);

 	config_finalize_register(sc->sc_dev, platinumfb_init);
 }

 static void
 platinumfb_init_cmap(struct platinumfb_softc *sc)
 {
     int i;
     uint8_t tmp;

     switch (sc->sc_cmode) {
     case PLATINUM_CMODE_8:
     default:
 	/* R3G3B2 colormap */
 	for (i = 0; i < 256; i++) {
 	    tmp = i & 0xe0;
 	    /*
 	     * replicate bits so 0xe0 maps to a red value of 0xff
 	     * in order to make white look actually white
 	     */
 	    tmp |= (tmp >> 3) | (tmp >> 6);
 	    sc->sc_cmap_red[i] = tmp;

 	    tmp = (i & 0x1c) << 3;
 	    tmp |= (tmp >> 3) | (tmp >> 6);
 	    sc->sc_cmap_green[i] = tmp;

 	    tmp = (i & 0x03) << 6;
 	    tmp |= tmp >> 2;
 	    tmp |= tmp >> 4;
 	    sc->sc_cmap_blue[i] = tmp;
 	}
 	break;

     case PLATINUM_CMODE_16:
 	for (i = 0; i < 32; i++) {
 	    tmp = 255 * i / 32;
 	    sc->sc_cmap_red[i] = tmp;
 	    sc->sc_cmap_green[i] = tmp;
 	    sc->sc_cmap_blue[i] = tmp;
 	}
 	for (i = 32; i < 256; i++)
 	{
 	    sc->sc_cmap_red[i] =  0;
 	    sc->sc_cmap_blue[i] = 0;
 	    sc->sc_cmap_green[i] = 0;
 	}
 	break;

     case PLATINUM_CMODE_32:
 	for (i = 0; i < 256; i++) {
 	    sc->sc_cmap_red[i] = i;
 	    sc->sc_cmap_green[i] = i;
 	    sc->sc_cmap_blue[i] = i;
 	}
 	break;
     }
 }

 static void
 platinumfb_restore_palette(struct platinumfb_softc *sc)
 {
     int i;
     for (i = 0; i < 256; i++) {
 	platinumfb_putpalreg(sc, i, sc->sc_cmap_red[i],
 			     sc->sc_cmap_green[i], sc->sc_cmap_blue[i]);
     }
 }

 static int
 platinumfb_init(device_t self)
 {
 	struct platinumfb_softc *sc = device_private(self);
 	const struct videomode *mode;
 	struct rasops_info *ri;

 	struct wsemuldisplaydev_attach_args aa;
 	bool is_console = FALSE;
 	long defattr;

 	struct platinumfb_setting *pfs = NULL;
 	int i;

 	/*
 	 * become console if OF variable "output-device" is "screen" or
 	 * contains "platinum", since normal OF video variables are unavailable
 	 */
 	int options;
 	char output_device[128];
 	options = OF_finddevice("/options");
 	if (options == 0 || 
 	    options == -1 ||
 	    OF_getprop(options, "output-device", output_device, sizeof(output_device)) == 0 ) {
 	    aprint_error_dev(sc->sc_dev, "could not get output-device prop, assuming not console\n");
 	}
 	else {
 	    if (strstr(output_device,"platinum") ||
 		strcmp(output_device,"screen") == 0 ) {
 		is_console = TRUE;
 	    }
 	}	

 	sc->sc_pfs = NULL;
 	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
 	sc->sc_on = WSDISPLAYIO_VIDEO_ON;

 	/* determine vram memory and dac clock type */
 	platinumfb_memory_size(sc);
 	platinumfb_dac_type(sc);

 	aprint_normal_dev(sc->sc_dev,"is_console %d dac 0x%x vram 0x%x\n",
 			  is_console, sc->sc_dac_type, sc->sc_vram);

 	for (i=0; i < sizeof(pfb_setting)/sizeof(pfb_setting[0]); i++)
 	{
 	    if (strcmp(PLATINUM_FB_VMODE, pfb_setting[i]->vmode_name)==0) {
 		pfs = pfb_setting[i];
 		break;
 	    }
 	}

 	if (pfs) {
 	    mode = pick_mode_by_ref(pfs->width, pfs->height, pfs->freq);
 	} else {
 	    aprint_error_dev(sc->sc_dev, "pick_mode_by_ref failed, using default\n");
 	    mode = pick_mode_by_ref(800, 600, 75);
 	}

 	if (platinumfb_set_mode(sc, mode, PLATINUM_FB_DEPTH) != 0) {
 	    aprint_error_dev(sc->sc_dev, "platinumfb_set_mode failed\n");
 	    return 0;
 	}

 	vcons_init(&sc->vd, sc, &platinumfb_defaultscreen,
 		   &platinumfb_accessops);
 	sc->vd.init_screen = platinumfb_init_screen;

 	ri = &platinumfb_console_screen.scr_ri;
 	vcons_init_screen(&sc->vd, &platinumfb_console_screen, 1, &defattr);

 	platinumfb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;

 	platinumfb_defaultscreen.textops = &ri->ri_ops;
 	platinumfb_defaultscreen.capabilities = ri->ri_caps;
 	platinumfb_defaultscreen.nrows = ri->ri_rows;
 	platinumfb_defaultscreen.ncols = ri->ri_cols;

 	if (is_console) {
 		wsdisplay_cnattach(&platinumfb_defaultscreen, ri, 0, 0,
 		    defattr);
 		vcons_replay_msgbuf(&platinumfb_console_screen);
 	}

 	aa.console = is_console;
 	aa.scrdata = &platinumfb_screenlist;
 	aa.accessops = &platinumfb_accessops;
 	aa.accesscookie = &sc->vd;

 	config_found(self, &aa, wsemuldisplaydevprint);

 	return 0;
 }

 static void
 platinumfb_set_hardware(struct platinumfb_softc *sc)
 {
     int i;
     bool one_bank = sc->sc_vram == PLATINUM_FB_BANK_SIZE;

     /* now start programming the chip */
     platinumfb_write_reg(sc, 24, 7);    /* turn off display */

     for (i = 0; i < 26; ++i)
 	platinumfb_write_reg(sc, i+32, sc->sc_pfs->regs[i]);

     platinumfb_write_reg(sc, 26+32, one_bank ? 
 			 sc->sc_pfs->offset[sc->sc_cmode] + 4 - sc->sc_cmode :
 			 sc->sc_pfs->offset[sc->sc_cmode]);

     /*
      * reg 16 apparently needs an address 0x10 less the where frame
      * buffer/ri_bits start for console text to be aligned.  In
      * addition, X memory maps (mmap) the frame buffer starting on
      * page boundaries.  So to get both X and console text aligned we
      * start at the first page up from sc_fb[0]. Starting at sc_fb[0]
      * did work on my machine but not sure if this negative offset
      * would be problematic elsewhere.
      *
      * Not sure why linux used different fb offsets for each mode, as
      * any addresses seemed to work as long as relative difference was
      * 0x10.
      */
     platinumfb_write_reg(sc, 16, platinumfb_page_align_up(sc) - 0x10);

     platinumfb_write_reg(sc, 18, sc->sc_pfs->pitch[sc->sc_cmode]);

     /* 
      * XXX register 19 setting looks wrong for 1 bank & 32 bpp.
      * 512x384 is only resolution that would use such a setting, but
      * that is not currently in videomodes.c
      */
     if (sc->sc_cmode == PLATINUM_CMODE_32 &&
 	(sc->sc_pfs->macmode == 1 || sc->sc_pfs->macmode == 2))
 	aprint_error_dev(sc->sc_dev, "platinumfb reg19 array out-of-bounds");

     platinumfb_write_reg(sc, 19, one_bank ? 
 			 sc->sc_pfs->mode[sc->sc_cmode+1] : /* XXX fix this for 32 bpp */
 			 sc->sc_pfs->mode[sc->sc_cmode]);

     platinumfb_write_reg(sc, 20, one_bank ? 0x11 : 0x1011);
     platinumfb_write_reg(sc, 21, 0x100);
     platinumfb_write_reg(sc, 22, 1);
     platinumfb_write_reg(sc, 23, 1);
     platinumfb_write_reg(sc, 26, 0xc00);
     platinumfb_write_reg(sc, 27, 0x235);
     /* platinumfb_write_reg(sc, 27, 0x2aa); */

     platinumfb_store_d2(sc, 0, one_bank ? sc->sc_pfs->dacula_ctrl[sc->sc_cmode] & 0xf :
                                           sc->sc_pfs->dacula_ctrl[sc->sc_cmode]);
     platinumfb_store_d2(sc, 1, 4);
     platinumfb_store_d2(sc, 2, 0);

     platinumfb_set_clock(sc);

     platinumfb_write_reg(sc, 24, 0);  /* turn display on */
 }

 static int
 platinumfb_set_mode(struct platinumfb_softc *sc,
     const struct videomode *mode, int depth)
 {
 	int i;

 	/* first find the parameter for the mode register */
 	i = 0;
 	while((i < __arraycount(pfb_setting)) &&
 	      (strcmp(mode->name, pfb_setting[i]->vmode_name) != 0))
 	    i++;

 	if (i >= __arraycount(pfb_setting)) {
 		aprint_error_dev(sc->sc_dev,
 		    "Can't find a mode register value for %s\n", 
 				 mode->name);
 		return EINVAL;
 	}

 	/* found a mode */
 	sc->sc_pfs = pfb_setting[i];

 	/* determine depth settings */
 	switch (depth) {
 	case 8:
 	default:
 	    sc->sc_depth = 8;
 	    sc->sc_cmode = PLATINUM_CMODE_8;
 	    break;
 	case 15:
 	case 16:
 	    /* 15 bpp but use 16 so X/wsfb works */
 	    sc->sc_depth = 16;
 	    sc->sc_cmode = PLATINUM_CMODE_16;
 	    break;
 	case 24:
 	case 32:
 	    /* 24 bpp but use 32 so X/wsfb works */
 	    sc->sc_depth = 32;
 	    sc->sc_cmode = PLATINUM_CMODE_32;
 	    break;
 	}

 	sc->sc_modereg = sc->sc_pfs->macmode;
 	sc->sc_videomode = mode;
 	sc->sc_height = mode->vdisplay;
 	sc->sc_width = mode->hdisplay;
 	sc->sc_linebytes = sc->sc_width * (1 << sc->sc_cmode) + platinumfb_line_tweak(sc);

 	/* check if we have enough video memory */
 	if (sc->sc_height * sc->sc_linebytes > sc->sc_vram - PAGE_SIZE) {
 	    aprint_error_dev(sc->sc_dev, "Not enough video RAM for %s\n",
 			     mode->name);
 	    return EINVAL;
 	}

 	/* set up and write colormap */
 	platinumfb_init_cmap(sc);
 	platinumfb_restore_palette(sc);

 	/* set hardware registers */
 	platinumfb_set_hardware(sc);

 	aprint_normal_dev(sc->sc_dev, "switched to %s in %d bit color\n",
 			  sc->sc_pfs->vmode_name, sc->sc_depth);
 	return 0;
 }

 static int
 platinumfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
 	struct lwp *l)
 {
         struct vcons_data *vd = v;
         struct platinumfb_softc *sc = vd->cookie;
         struct wsdisplay_fbinfo *wdf;
         struct vcons_screen *ms = vd->active;
 	int i;

         switch (cmd) {
         case WSDISPLAYIO_GTYPE:
                 *(u_int *)data = WSDISPLAY_TYPE_PLATINUM;
                 return 0;

         case WSDISPLAYIO_GINFO:
                 wdf = (void *)data;
                 wdf->height = ms->scr_ri.ri_height;
                 wdf->width = ms->scr_ri.ri_width;
                 wdf->depth = ms->scr_ri.ri_depth;
                 wdf->cmsize = 256;
                 return 0;

         case WSDISPLAYIO_GVIDEO:
                 *(int *)data = sc->sc_on;
                 return 0;

         case WSDISPLAYIO_SVIDEO:
 		/* 
 		 * poor man's screen blanking, just write zeros to colormap
 		 * registers but don't save in softc.  
 		 */
                 if (*(int *)data != sc->sc_on) {
                     sc->sc_on = (sc->sc_on == WSDISPLAYIO_VIDEO_ON ?
 				 WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON);

 		    /* XXX need to lock colormap? */
                     if (sc->sc_on == WSDISPLAYIO_VIDEO_OFF)
                         for (i=0; i < 256; i++)
                             platinumfb_putpalreg(sc, i, 0, 0, 0);
                     else
 			platinumfb_restore_palette(sc);
                 }
                 return 0;

         case WSDISPLAYIO_GETCMAP:
 	        if (sc->sc_cmode == PLATINUM_CMODE_8)
 		    return platinumfb_getcmap(sc, (struct wsdisplay_cmap *)data);
 		else
 		    return 0;

         case WSDISPLAYIO_PUTCMAP:
 	        if (sc->sc_cmode == PLATINUM_CMODE_8)
 		    return platinumfb_putcmap(sc, (struct wsdisplay_cmap *)data);
 		else
 		    return 0;

         case WSDISPLAYIO_SMODE: {
 		int new_mode = *(int*)data;
 		if (new_mode != sc->sc_mode) {
 		        sc->sc_mode = new_mode;
 			platinumfb_restore_palette(sc);

 			if (new_mode == WSDISPLAYIO_MODE_EMUL)
 			    vcons_redraw_screen(ms);
 		}
 		}
 		return 0;

 	case WSDISPLAYIO_LINEBYTES:
 	        *(u_int *)data = sc->sc_linebytes;
 		return 0;

 	case WSDISPLAYIO_GET_FBINFO: {
 	    struct wsdisplayio_fbinfo *fbi = data;
 	    return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
 	}

 	}
 	return EPASSTHROUGH;
 }

 static paddr_t
 platinumfb_mmap(void *v, void *vs, off_t offset, int prot)
 {
 	struct vcons_data *vd = v;
 	struct platinumfb_softc *sc = vd->cookie;
 	paddr_t pa = -1;
 	paddr_t fb_aligned = platinumfb_page_align_up(sc);
 	paddr_t fb_vram = sc->sc_vram - (fb_aligned - (paddr_t)sc->sc_fb);

 	/* XXX need to worry about superuser or mapping other registers? */

 	if (offset >= 0 && offset < fb_vram)
 	    pa = fb_aligned + offset;

 	return pa;
 }

 static void
 platinumfb_init_screen(void *cookie, struct vcons_screen *scr,
     int existing, long *defattr)
 {
 	struct platinumfb_softc *sc = cookie;
 	struct rasops_info *ri = &scr->scr_ri;

 	memset(ri, 0, sizeof(struct rasops_info));
 	ri->ri_depth = sc->sc_depth;
 	ri->ri_width = sc->sc_width;
 	ri->ri_height = sc->sc_height;
 	ri->ri_stride = sc->sc_linebytes;
 	ri->ri_bits = (u_char*)platinumfb_page_align_up(sc);
 	ri->ri_flg = RI_FULLCLEAR;

 	if (existing)
 	    ri->ri_flg |= RI_CLEAR;

 	switch (sc->sc_cmode) {
 	case PLATINUM_CMODE_8:
 	default:
 	    ri->ri_flg |= RI_ENABLE_ALPHA | RI_8BIT_IS_RGB;

 	    break;
 	case PLATINUM_CMODE_16:
 	    if ( strcmp(sc->sc_pfs->vmode_name, "640x480x60") == 0 ||
 		 strcmp(sc->sc_pfs->vmode_name, "800x600x75") == 0 )
 		ri->ri_flg |= RI_ENABLE_ALPHA;

 	    ri->ri_rnum = 5;
 	    ri->ri_rpos = 10;
 	    ri->ri_gnum = 5;
 	    ri->ri_gpos = 5;
 	    ri->ri_bnum = 5;
 	    ri->ri_bpos = 0;

 	    break;
 	case PLATINUM_CMODE_32:
 	    if ( strcmp(sc->sc_pfs->vmode_name, "640x480x60") == 0 ||
 		 strcmp(sc->sc_pfs->vmode_name, "800x600x75") == 0 )
 		ri->ri_flg |= RI_ENABLE_ALPHA;

 	    ri->ri_rnum = 8;
 	    ri->ri_rpos = 16;
 	    ri->ri_gnum = 8;
 	    ri->ri_gpos = 8;
 	    ri->ri_bnum = 8;
 	    ri->ri_bpos = 0;

 	    break;
 	}

 	scr->scr_flags |= VCONS_DONT_READ;

 	rasops_init(ri, 0, 0);
 	ri->ri_caps = WSSCREEN_WSCOLORS;

 	rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
 		    sc->sc_width / ri->ri_font->fontwidth);

 	ri->ri_hw = scr;
 }

 static int
 platinumfb_putcmap(struct platinumfb_softc *sc, struct wsdisplay_cmap *cm)
 {
 	u_char *r, *g, *b;
 	u_int index = cm->index;
 	u_int count = cm->count;
 	int i, error;
 	u_char rbuf[256], gbuf[256], bbuf[256];

 	if (cm->index >= 256 || cm->count > 256 ||
 	    (cm->index + cm->count) > 256)
 		return EINVAL;
 	error = copyin(cm->red, &rbuf[index], count);
 	if (error)
 		return error;
 	error = copyin(cm->green, &gbuf[index], count);
 	if (error)
 		return error;
 	error = copyin(cm->blue, &bbuf[index], count);
 	if (error)
 		return error;

 	memcpy(&sc->sc_cmap_red[index], &rbuf[index], count);
 	memcpy(&sc->sc_cmap_green[index], &gbuf[index], count);
 	memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count);

 	/* write colormap registers if not currently blanked */
 	if (sc->sc_on == WSDISPLAYIO_VIDEO_ON) {
 	    r = &sc->sc_cmap_red[index];
 	    g = &sc->sc_cmap_green[index];
 	    b = &sc->sc_cmap_blue[index];

 	    for (i = 0; i < count; i++) {
 		platinumfb_putpalreg(sc, index, *r, *g, *b);
 		index++;
 		r++, g++, b++;
 	    }
 	}

 	return 0;
 }

 static int
 platinumfb_getcmap(struct platinumfb_softc *sc, struct wsdisplay_cmap *cm)
 {
 	u_int index = cm->index;
 	u_int count = cm->count;
 	int error;

 	if (index >= 255 || count > 256 || index + count > 256)
 		return EINVAL;

 	error = copyout(&sc->sc_cmap_red[index],   cm->red,   count);
 	if (error)
 		return error;
 	error = copyout(&sc->sc_cmap_green[index], cm->green, count);
 	if (error)
 		return error;
 	error = copyout(&sc->sc_cmap_blue[index],  cm->blue,  count);
 	if (error)
 		return error;

 	return 0;
 }

From: Michael <macallan@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Fri, 21 Nov 2014 21:20:16 -0500

 Hello,

 On Fri, 21 Nov 2014 16:55:01 +0000 (UTC)
 scole_mail <scole_mail@gmx.com> wrote:

 >  After a lot of trial and error, I have some fixes to get console and
 >  X/wsfb working for 8/16/32 bpp and various resolutions. Virtual
 >  terminal switching also works (though I'm not responsible for that).

 Nice!

 >  Some other issue still remain
 >  
 >  - Right-Shift, Right-Option, Right-Command weren't working for me in
 >  X.  I have apple adb keyboard but haven't looked into this yet

 I added support for that in adbkbd a little while ago, by default all
 ADB keyboard treat the right Alt/Control/Shift keys the same as the
 left - it works at least on my Extended II ( not on my iBook, the right
 shift is still identical to the left ). Might be worth sprinkling some
 printf()s to figure out what exactly your keyboard type is.

 >  - Still need to test X with a mouse as I don't have one (yet) that
 >  works on my machine.  I should be getting an adb one soon to try.

 I have a cheap ohci card in my 7200.

 >  - I made various attempts to switch from 8bpp console to 16bpp X/wsfb
 >  but I couldn't get it to work.  The wsfb man page seems to indicate
 >  changing resolutions or depths isn't supported.  My work-around was
 >  to add
 >  	#define PLATINUM_FB_DEPTH 16
 >  	#define PLATINUM_FB_VMODE "800x600x75"
 >  
 >  at top of platinumfb.c.

 Many of my drivers will switch depth on ioctl(WSDISPLAYIO_SMODE,
 WSDISPLAYIO_MODE_DUMBFB) so X gets the colours and the console gets
 8bit speed.

 have fun
 Michael

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Sat, 22 Nov 2014 10:14:18 -0500

 I can get it to switch from 8bit/console to 16bit/X if I change modes
 in MAPPED not DUMBFB:

          case WSDISPLAYIO_SMODE: {
 		int new_mode = *(int*)data;
 		if (new_mode != sc->sc_mode) {
 		    int depth = new_mode == WSDISPLAYIO_MODE_EMUL ? 8 : 16;

 		    switch(new_mode) {
 		    case WSDISPLAYIO_MODE_EMUL:
 		    case WSDISPLAYIO_MODE_MAPPED:
  		  //case WSDISPLAYIO_MODE_DUMBFB:   // 8 bit ?
 		        sc->sc_mode = new_mode;
 			platinumfb_set_mode(sc, sc->sc_videomode, depth);
 			platinumfb_set_rasops(sc, &ms->scr_ri, true);

 			if (new_mode == WSDISPLAYIO_MODE_EMUL)
 			    vcons_redraw_screen(ms);
 		    }
 		}
 		}
 		return 0;

 Guess I don't understand the difference between MAPPED and DUMBFB.  If
 I do
 		    case WSDISPLAYIO_MODE_EMUL:
 		  //case WSDISPLAYIO_MODE_MAPPED:
  		    case WSDISPLAYIO_MODE_DUMBFB:

 X always starts in 8 bit, so it seems like I need to set depth when MAPPED ?

From: Michael <macallan@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Sat, 22 Nov 2014 10:35:18 -0500

 Hello,

 On Sat, 22 Nov 2014 15:15:00 +0000 (UTC)
 scole_mail <scole_mail@gmx.com> wrote:

 >  Guess I don't understand the difference between MAPPED and DUMBFB.  If
 >  I do
 >  		    case WSDISPLAYIO_MODE_EMUL:
 >  		  //case WSDISPLAYIO_MODE_MAPPED:
 >   		    case WSDISPLAYIO_MODE_DUMBFB:
 >  
 >  X always starts in 8 bit, so it seems like I need to set depth when MAPPED ?

 Many drivers treat them the same, The difference is this:
 In WSDISPLAYIO_MODE_DUMBFB we can map the framebuffer at offset 0, and nothing else. This is what xf86-video-wsfb uses.
 In WSDISPLAYIO_MODE_MAPPED we can map the actual hardware, at their respective bus addresses ( for PCI cards for example ) or something similar. A few drivers use this, for example xf86-video-crime ( for the SGI O2's onboard graphics hardware ). This is intended for hardware that can not or should not be mapped in other ways.
 They're kept separate since the framebuffer at 0 may overlap with bus addresses used by the hardware.

 have fun
 Michael

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Mon, 5 Jan 2015 15:45:58 -0500

 I got my powermac 7200 to boot off its scsi disk finally.  The disk
 used was a replacement because the stock one was missing.

 Code changes are in
    src/sys/arch/macppc/stand/bootxx/bootxx.c
    src/sys/arch/macppc/stand/ofwboot/Locore.c
 which were basically to deal with 601 bats and alignment exceptions.
 The esp driver worked fine for me unchanged.

 In openfirmware 1.0.5, this would boot partition zero disk:
    boot scsi/sd@0:0

 or for "permanent" settings:
    setenv boot-device  scsi/sd@0:0
    setenv boot-command catch 5000 ms boot
    setenv auto-boot?   true
    reset-all

 I did add a jumper to the scsi disk to make it spin up at power-on.  I
 didn't trying booting off of the cd or floppy, because they both are
 broken on my machine.

 Just for completeness, this command can boot an iso image
 installed to the hard disk:
    boot scsi/sd@0:0,OFWBOOT.XCF;1 NETBSD.;1

 When I used sysinst, it seemed to be doing:

    /usr/sbin/installboot /dev/rsd0a /usr/mdec/bootxx /boot

 which didn't work so I did:

   mount -t ffs /dev/sd0a /tmp/mnt
   cp .../ofwboot /tmp/mnt/
   umount /tmp/mnt
   /usr/sbin/installboot -v /dev/rsd0c /usr/mdec/bootxx /ofwboot
   File system:         /dev/rsd0c
   File system type:    ffs (blocksize 16384, needswap 0)
   Primary bootstrap:   /home/scole/bootxx
   Secondary bootstrap: /ofwboot
   Bootstrap start sector: 4
   Bootstrap byte count:   1900
   Bootstrap block table:  118 entries of 16384 bytes available, 5 used: 5440 5472 5504 5536 55128
   Writing bootstrap

 after disklabeling and newfs.  Sometimes I had to reboot after doing
 the disklabel for newfs to work.  It seems like kernel wasn't aware of
 the new disklabel.

 Here is the disklabel for my disk which only had a single partion:

 pm7200# disklabel sd0
 # /dev/rsd0c:
 type: unknown
 disk: 0662S12       !
 label: 
 flags:
 bytes/sector: 512
 sectors/track: 99
 tracks/cylinder: 5
 sectors/cylinder: 495
 cylinders: 4119
 total sectors: 2055035
 rpm: 3600
 interleave: 1
 trackskew: 0
 cylinderskew: 0
 headswitch: 0           # microseconds
 track-to-track seek: 0  # microseconds
 drivedata: 0 

 16 partitions:
 #        size    offset     fstype [fsize bsize cpg/sgs]
  a:   2055035         0     4.2BSD   2048 16384     0  # (Cyl.      0 -   4151*)
  c:   2055035         0     unused      0     0        # (Cyl.      0 -   4151*)

 These code changes had no effect, good or bad, on trying to boot gcc
 4.8 ofwboot.xcf over ethernet which doesn't work:
 http://mail-index.netbsd.org/port-macppc/2014/12/23/msg002129.html

 I had all wedge support commented out in the kernel.

 Index: sys/arch/macppc/stand/bootxx/bootxx.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/macppc/stand/bootxx/bootxx.c,v
 retrieving revision 1.18
 diff -b -u -r1.18 bootxx.c
 --- sys/arch/macppc/stand/bootxx/bootxx.c	14 Mar 2009 21:04:12 -0000	1.18
 +++ sys/arch/macppc/stand/bootxx/bootxx.c	5 Jan 2015 18:01:42 -0000
 @@ -33,6 +33,7 @@

  #include <sys/types.h>
  #include <powerpc/oea/bat.h>
 +#include <powerpc/oea/spr.h>

  #include <sys/bootblock.h>

 @@ -76,7 +77,13 @@
  "	sync			\n"

  "	li	%r0,0		\n"
 -"	mtdbatu	3,%r0		\n"
 +"                               \n"     /* test for 601 */
 +"       mfspr   %r9,287         \n"     /* mfpvbr %r9 PVR = 287 */
 +"       srwi    %r9,%r9,0x10    \n"
 +"       cmpi    0,1,%r9,0x02    \n"     /* 601 CPU = 0x0001 */
 +"       blt     2f              \n"     /* skip over non-601 BAT setup */
 +"                               \n"
 +"       mtdbatu 3,%r0           \n"     /* non-601 BAT */
  "	mtibatu	3,%r0		\n"
  "	isync			\n"
  "	li	%r8,0x1ffe	\n"	/* map the lowest 256MB */
 @@ -86,13 +93,64 @@
  "	mtibatl	3,%r9		\n"
  "	mtibatu	3,%r8		\n"
  "	isync			\n"
 +"       b 3f                    \n"
 +"                               \n"
 +"2:                             \n"
 +"       mfmsr   %r8             \n"     /* 601 BAT */
 +"       mtmsr   %r0             \n"
 +"       isync                   \n"
 +"                               \n"
 +"       mtibatu 0,%r0           \n"
 +"       mtibatu 1,%r0           \n"
 +"       mtibatu 2,%r0           \n"
 +"       mtibatu 3,%r0           \n"
 +"                               \n"
 +"       li      %r9,0x7f        \n"
 +"       mtibatl 0,%r9           \n"
 +"       li      %r9,0x1a        \n"
 +"       mtibatu 0,%r9           \n"
 +"                               \n"
 +"       lis %r9,0x80            \n"
 +"       addi %r9,%r9,0x7f       \n"
 +"       mtibatl 1,%r9           \n"
 +"       lis %r9,0x80            \n"
 +"       addi %r9,%r9,0x1a       \n"
 +"       mtibatu 1,%r9           \n"
 +"                               \n"
 +"       lis %r9,0x100           \n"
 +"       addi %r9,%r9,0x7f       \n"
 +"       mtibatl 2,%r9           \n"
 +"       lis %r9,0x100           \n"
 +"       addi %r9,%r9,0x1a       \n"
 +"       mtibatu 2,%r9           \n"
 +"                               \n"
 +"       lis %r9,0x180           \n"
 +"       addi %r9,%r9,0x7f       \n"
 +"       mtibatl 3,%r9           \n"
 +"       lis %r9,0x180           \n"
 +"       addi %r9,%r9,0x1a       \n"
 +"       mtibatu 3,%r9           \n"
 +"                               \n"
 +"       isync                   \n"
 +"                               \n"
 +"       mtmsr   %r8             \n"
 +"       isync                   \n"
 +"                               \n"

  	/*
  	 * setup 32 KB of stack with 32 bytes overpad (see above)
  	 */
 +"3:                             \n"
  "	lis	%r1,(stack+32768)@ha\n"
  "	addi	%r1,%r1,(stack+32768)@l\n"
 -"	stw	%r0,0(%r1)	\n"	/* terminate the frame link chain */
 +        /*
 +         * terminate the frame link chain,
 +         * clear by bytes to avoid ppc601 alignment exceptions
 +         */
 +"       stb     %r0,0(%r1)      \n"
 +"       stb     %r0,1(%r1)      \n"
 +"       stb     %r0,2(%r1)      \n"
 +"       stb     %r0,3(%r1)      \n"

  "	b	startup		\n"
  );
 @@ -257,6 +315,7 @@
  void
  startup(int arg1, int arg2, void *openfirm)
  {
 +        uint32_t pvr;
  	int fd, blk, chosen, options, j;
  	size_t i;
  	char *addr;
 @@ -302,6 +361,9 @@
  	}
  	putstr(". done!\r\nstarting stage 2...\r\n");

 +        __asm volatile ("mfpvr %0" : "=r"(pvr));
 +
 +        if (pvr != MPC601) {
  	/*
  	 * enable D/I cache
  	 */
 @@ -313,6 +375,7 @@
  		"isync"
  	   ::	"r"(BATU(0, BAT_BL_256M, BAT_Vs)),
  		"r"(BATL(0, 0, BAT_PP_RW)));
 +        }

  	entry_point(0, 0, openfirm);
  	for (;;);			/* just in case */

 Index: sys/arch/macppc/stand/ofwboot/Locore.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/macppc/stand/ofwboot/Locore.c,v
 retrieving revision 1.25
 diff -b -u -r1.25 Locore.c
 --- sys/arch/macppc/stand/ofwboot/Locore.c	26 Feb 2014 21:42:40 -0000	1.25
 +++ sys/arch/macppc/stand/ofwboot/Locore.c	5 Jan 2015 18:01:44 -0000
 @@ -70,9 +70,9 @@
  "	isync			\n"
  "				\n"
  "				\n" /* test for 601 */
 -"       mfspr   %r0,287      	\n" /* mfpvbr %r0 PVR = 287 */
 -"       srwi    %r0,%r0,0x10   	\n"
 -"       cmpi    0,1,%r0,0x02  	\n" /* 601 CPU = 0x0001 */
 +"       mfspr   %r9,287         \n" /* mfpvbr %r9 PVR = 287 */
 +"       srwi    %r9,%r9,0x10    \n"
 +"       cmpi    0,1,%r9,0x02    \n" /* 601 CPU = 0x0001 */
  "       blt     1f		\n" /* skip over non-601 BAT setup */
  	/*non PPC 601 BATs*/
  "	mtibatu	0,%r0		\n"
 @@ -141,7 +141,13 @@
  "				\n"
  "5:	cmpw	0,%r8,%r9	\n"
  "	bge	6f		\n"
 -"	stw	%r0,0(%r8)	\n"
 +        /*
 +         * clear by bytes to avoid ppc601 alignment exceptions
 +         */
 +"       stb     %r0,0(%r8)      \n"
 +"       stb     %r0,1(%r8)      \n"
 +"       stb     %r0,2(%r8)      \n"
 +"       stb     %r0,3(%r8)      \n"
  "	addi	%r8,%r8,4	\n"
  "	b	5b		\n"
  "				\n"

From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Mon, 5 Jan 2015 23:37:59 +0100

 On Mon, Jan 05, 2015 at 08:50:01PM +0000, scole_mail wrote:

 >  -"	stw	%r0,0(%r1)	\n"	/* terminate the frame link chain */
 >  +        /*
 >  +         * terminate the frame link chain,
 >  +         * clear by bytes to avoid ppc601 alignment exceptions
 >  +         */
 [..]
 >  -"	stw	%r0,0(%r8)	\n"
 >  +        /*
 >  +         * clear by bytes to avoid ppc601 alignment exceptions
 >  +         */

 Maybe a stupid question: why are %r1/%r8 not properly aligned here?

 Martin

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: port-macppc-maintainer@netbsd.org, gnats-admin@netbsd.org,
	netbsd-bugs@netbsd.org
Subject: Re: port-macppc/48600
Date: Mon, 5 Jan 2015 20:33:39 -0500

 On Mon, Jan 05, 2015 at 10:40:04PM +0000, Martin Husemann wrote:
 >  
 >  Maybe a stupid question: why are %r1/%r8 not properly aligned here?
 >  
 >  Martin
 >  

 The 601 will get alignment exceptions if operands cross page
 boundaries or word operands end in 0xffd - 0xfff.  The latter was what
 was happening to me.  Byte operands don't generate alignment
 exceptions.

 I'm not sure why code in Locore.c didn't cause issues earlier with
 ofwboot.xcf.  I seemed only to get the exceptions when booting off the
 disk.

From: christos@zoulas.com (Christos Zoulas)
To: scole_mail <scole_mail@gmx.com>, gnats-bugs@NetBSD.org
Cc: port-macppc-maintainer@netbsd.org, gnats-admin@netbsd.org, 
	netbsd-bugs@netbsd.org
Subject: Re: port-macppc/48600
Date: Mon, 5 Jan 2015 20:59:56 -0500

 On Jan 5,  8:33pm, scole_mail@gmx.com (scole_mail) wrote:
 -- Subject: Re: port-macppc/48600

 | On Mon, Jan 05, 2015 at 10:40:04PM +0000, Martin Husemann wrote:
 | >  
 | >  Maybe a stupid question: why are %r1/%r8 not properly aligned here?
 | >  
 | >  Martin
 | >  
 | 
 | The 601 will get alignment exceptions if operands cross page
 | boundaries or word operands end in 0xffd - 0xfff.  The latter was what
 | was happening to me.  Byte operands don't generate alignment
 | exceptions.
 | 
 | I'm not sure why code in Locore.c didn't cause issues earlier with
 | ofwboot.xcf.  I seemed only to get the exceptions when booting off the
 | disk.

 This could be what is causing problems with PearPC. Have you tried that.
 It currently dies loading the kernel. I will try with your changes.

 christos

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: port-macppc-maintainer@netbsd.org, gnats-admin@netbsd.org,
	netbsd-bugs@netbsd.org
Subject: Re: port-macppc/48600
Date: Tue, 6 Jan 2015 09:45:02 -0500

 On Tue, Jan 06, 2015 at 02:05:00AM +0000, Christos Zoulas wrote:
 > The following reply was made to PR port-macppc/48600; it has been noted by GNATS.
 > 
 >  This could be what is causing problems with PearPC. Have you tried that.
 >  It currently dies loading the kernel. I will try with your changes.
 >  
 >  christos
 >  

 When I looked last, which was a long time ago, I thought PearPC
 couldn't emulate a 601 and was doing some kind of G4.  So I don't if
 it would have these kind of alignment issues.

 Just browsing pkgsrc, another emulator that can do powerpc is QEMU,
 but I haven't tried that one either.

 Thanks

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-macppc/48600
Date: Fri, 31 Jul 2015 14:02:46 -0400

 I've included an updated platinumfb.c file so the console will be 8
 bit, and built-in X config will be 16 bit.  The bpp depth can be
 changed by updating PLATINUM_FB_DEPTH and PLATINUM_CONSOLE_DEPTH, and
 re-compiling the kernel.  I tested X with a usb mouse and usb keyboard
 and the buttons seemed to all work with a recent build.

 I think the only things left to check in for this PR are the
 platinumfb files, and 601 bootxx.c/Locore.c changes for booting off
 the disk, which I tested and work fine (without wedges).

 I believe the PR could then be closed out once those are checked in.

 Thanks

 sys/arch/macppc/dev/platinumfb.c
 -----------------------------------------------------------------
 /*
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */

 /* A console driver for Apple's Platinum onboard video controller,
  * found in (all?) Catalyst logic boards including the Powermac 7200.
  *
  * Used valkyriefb.c from NetBSD, and platinumfb.c/platinumfb.h from
  * Linux sources as templates.
  *
  * Platinum is broken regarding openfirmware video variables.  In OF,
  * for a powermac 7200, doing "dev /platinum .properties" results in:
  *
  *	name                    platinum
  *	device_type             display
  *	model                   AAPL,343S1184
  *	AAPL,connector          monitor
  *	reg                     F8000000  00000800
  *	                        F1000000  01000000
  *	AAPL,interrupts         0000001E
  *
  * The first reg is the register set, and the second is for the
  * framebuffer.  There is also a set of colormap registers hardcoded
  * in platinumfbreg.h that (I think) aren't in openfirmware.
  *
  * powermac 7200 VRAM min and max limits are 1 and 4 Mb respectively.
  * OF claims 16M so we don't use that value.  If other machines can
  * can have more or less VRAM this code will need to be modified
  */

 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: platinumfb.c,v 1.1 2014/10/31 12:00:00 macallan Exp $");

 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/device.h>

 #include <uvm/uvm_param.h>

 #include <dev/ofw/openfirm.h>

 #include <machine/autoconf.h>
 #include <machine/pio.h>

 #include <dev/wscons/wsdisplayvar.h>
 #include <dev/wscons/wsconsio.h>
 #include <dev/wsfont/wsfont.h>
 #include <dev/rasops/rasops.h>
 #include <dev/wscons/wsdisplay_vconsvar.h>

 #include <dev/videomode/videomode.h>

 #include <arch/macppc/dev/platinumfbreg.h>

 #include <sys/sysctl.h>

 #include "opt_wsemul.h"

 /*
  * here is a link of supported modes and resolutions:
  *  https://support.apple.com/kb/SP343?locale=en_US
  *
  * default console and X bpp/depth for built-in X config file,
  * select 8 or 16 or 32. 
  *
  */
 #define PLATINUM_CONSOLE_DEPTH 8
 #define PLATINUM_FB_DEPTH      16

 /*
  * resolution, from one of platinumfb_setting vmode_name's.
  */
 #define PLATINUM_FB_VMODE "800x600x75"

 struct platinumfb_setting {
         char vmode_name[24];
 	int32_t width;
 	int32_t height;
     	uint8_t freq;
 	uint8_t macmode;

 	int32_t	pitch[3];
 	uint32_t regs[26];
 	uint8_t offset[3];
 	uint8_t mode[3];
 	uint8_t dacula_ctrl[3];
 	uint8_t clock_params[2][2];
 };

 struct platinumfb_softc {
 	device_t sc_dev;
 	int sc_node;

         uint8_t *sc_reg;
 	uint32_t sc_reg_size;

     	uint8_t *sc_cmap;
 	uint32_t sc_cmap_size;

 	uint8_t *sc_fb;
 	uint32_t sc_fb_size;

 	int sc_depth;
 	int sc_width, sc_height, sc_linebytes;
 	const struct videomode *sc_videomode;
 	uint8_t sc_modereg;

         int sc_mode;

 	u_char sc_cmap_red[256];
 	u_char sc_cmap_green[256];
 	u_char sc_cmap_blue[256];

 	struct vcons_data vd;

         uint8_t sc_cmode;
         uint8_t sc_dac_type;
         uint32_t sc_vram;
         int sc_on;
         struct platinumfb_setting *sc_pfs;
 };

 #define DIV2	0x20
 #define DIV4	0x40
 #define DIV8	0x60
 #define DIV16	0x80

 static struct platinumfb_setting platinum_5 = {
     "640x480x60",
     640, 480, 60, 5,
     { 672, 1312, 2592 },
     { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
       0, 0x15e, 0xc8, 0x18, 0x18f, 0x2f, 0x35, 0x3e,
       0x42, 0x182, 0x18e, 0x41a, 0x418, 2, 7, 0x44,
       0x404, 0x408 }, { 0x34, 0x3c, 0x41 },
     { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
     {{ 26, 0 + DIV8 }, { 14, 2 + DIV4 }}
 };

 static struct platinumfb_setting platinum_12 = {
     "800x600x75",
     800, 600, 75, 12,
     { 832, 1632, 3232 },
     { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
       0, 0x1ce, 0x108, 0x14, 0x20f, 0x27, 0x30, 0x39,
       0x72, 0x202, 0x20e, 0x4e2, 0x4e0, 4, 9, 0x2e,
       0x4de, 0x4df }, { 0x64, 0x6c, 0x71 },
     { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
     {{ 122, 7 + DIV4 }, { 62, 9 + DIV2 }}
 };

 static struct platinumfb_setting platinum_14 = {
     "1024x768x60",
     1024, 768, 60, 14,
     { 1056, 2080, 4128 },
     { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
       0, 0x25a, 0x14f, 0x22, 0x29f, 0x43, 0x49, 0x5b,
       0x8e, 0x28e, 0x29e, 0x64c, 0x64a, 0xa, 0xf, 0x44,
       0x644, 0x646 }, { 0x80, 0x88, 0x8d },
     { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
     {{ 71, 6 + DIV2 }, { 118, 13 + DIV2 }}
 };

 static struct platinumfb_setting platinum_20 = {
     "1280x1024x75",
     1280, 1024, 75, 20,
     { 1312, 2592, 2592 },
     { 0xffc, 4, 0, 0, 0, 0, 0x428, 0,
       0, 0xb3, 0xd3, 0x12, 0x1a5, 0x23, 0x28, 0x2d,
       0x5e, 0x19e, 0x1a4, 0x854, 0x852, 4, 9, 0x50,
       0x850, 0x851 }, { 0x58, 0x5d, 0x5d },
     { 0, 0xff, 0xff }, { 0x51, 0x55, 0x55 },
     {{ 45, 3 }, { 66, 7 }}
 };

 static struct platinumfb_setting *pfb_setting[] = {
     &platinum_5,
     &platinum_12,
     &platinum_14,
     &platinum_20
 };

 static struct vcons_screen platinumfb_console_screen;

 static int	platinumfb_match(device_t, cfdata_t, void *);
 static void	platinumfb_attach(device_t, device_t, void *);

 CFATTACH_DECL_NEW(platinumfb, sizeof(struct platinumfb_softc),
     platinumfb_match, platinumfb_attach, NULL, NULL);

 static int	platinumfb_init(device_t);
 static int 	platinumfb_set_mode(struct platinumfb_softc *,
 				    const struct videomode *, int);
 static void     platinumfb_set_rasops(struct platinumfb_softc *,
 				      struct rasops_info *, int);
 static int	platinumfb_ioctl(void *, void *, u_long, void *, int,
 				 struct lwp *);
 static paddr_t	platinumfb_mmap(void *, void *, off_t, int);
 static void	platinumfb_init_screen(void *, struct vcons_screen *, int,
 				       long *);
 static int	platinumfb_putcmap(struct platinumfb_softc *,
 				   struct wsdisplay_cmap *);
 static int 	platinumfb_getcmap(struct platinumfb_softc *,
 				   struct wsdisplay_cmap *);
 static void	platinumfb_init_cmap(struct platinumfb_softc *);
 static void	platinumfb_restore_palette(struct platinumfb_softc *);
 static void	platinumfb_putpalreg(struct platinumfb_softc *,
 				     uint8_t, uint8_t, uint8_t, uint8_t);
 static uint32_t platinumfb_line_tweak(struct platinumfb_softc *);
 static paddr_t	platinumfb_page_align_up(struct platinumfb_softc *);
 static void 	platinumfb_set_clock(struct platinumfb_softc *);
 static void	platinumfb_dac_type(struct platinumfb_softc *);
 static void	platinumfb_memory_size(struct platinumfb_softc *);
 static void	platinumfb_set_hardware(struct platinumfb_softc *);

 static inline void platinumfb_write_reg(struct platinumfb_softc *,
 					int, uint32_t);
 static inline uint32_t platinumfb_read_reg(struct platinumfb_softc *, int);
 static inline void platinumfb_write_cmap_reg(struct platinumfb_softc *, 
 					     int, uint8_t);
 static inline uint8_t platinumfb_read_cmap_reg(struct platinumfb_softc *, int);
 static inline void platinumfb_store_d2(struct platinumfb_softc *, 
 				       uint8_t, uint8_t);

 struct wsscreen_descr platinumfb_defaultscreen = {
 	"default",
 	0, 0,
 	NULL,
 	8, 16,
 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
 	NULL,
 };

 const struct wsscreen_descr *_platinumfb_scrlist[] = {
 	&platinumfb_defaultscreen,
 	/* XXX other formats, graphics screen? */
 };

 struct wsscreen_list platinumfb_screenlist = {
 	sizeof(_platinumfb_scrlist) / sizeof(struct wsscreen_descr *),
 	_platinumfb_scrlist
 };

 struct wsdisplay_accessops platinumfb_accessops = {
 	platinumfb_ioctl,
 	platinumfb_mmap,
 	NULL,
 	NULL,
 	NULL,
 	NULL,	/* load_font */
 	NULL,	/* polls */
 	NULL,	/* scroll */
 };

 static inline void
 platinumfb_write_reg(struct platinumfb_softc *sc, int reg, uint32_t val)
 {
     out32(sc->sc_reg + PLATINUM_REG_OFFSET_ADDR(reg), val);
 }

 static inline uint32_t
 platinumfb_read_reg(struct platinumfb_softc *sc, int reg)
 {
     return in32(sc->sc_reg + PLATINUM_REG_OFFSET_ADDR(reg));
 }

 static inline void
 platinumfb_write_cmap_reg(struct platinumfb_softc *sc, 
 			  int reg_offset, uint8_t val)
 {
     out8(sc->sc_cmap + reg_offset, val);
 }

 static inline uint8_t
 platinumfb_read_cmap_reg(struct platinumfb_softc *sc, int reg_offset)
 {
     return in8(sc->sc_cmap + reg_offset);
 }

 static inline void
 platinumfb_store_d2(struct platinumfb_softc *sc, 
 			  uint8_t a, uint8_t d)
 {
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, a + 32);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_D2_OFFSET, d);
 }

 static void
 platinumfb_putpalreg(struct platinumfb_softc *sc,
     uint8_t reg, uint8_t r, uint8_t g, uint8_t b)
 {
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, reg);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_LUT_OFFSET, r);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_LUT_OFFSET, g);
     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_LUT_OFFSET, b);
 }

 static uint32_t
 platinumfb_line_tweak(struct platinumfb_softc *sc)
 {
     /* bytes per line adjustment depending on resolution and depth */
     if (sc->sc_cmode > PLATINUM_CMODE_8 &&
 	strcmp(sc->sc_pfs->vmode_name, "832x624x75") == 0)
 	return 0x10;
     else
 	return 0x20;
 }

 static paddr_t
 platinumfb_page_align_up(struct platinumfb_softc *sc)
 {
     /* round up framebuffer address to the next highest page */
     paddr_t addr = (paddr_t)sc->sc_fb;
     paddr_t ret = round_page(addr);

     if (ret == addr)
 	ret = round_page(addr + 1);

     return ret;
 }

 /* 2 versions of platinum clock, older one uses clock[1] and
  *     freq = 14.3Mhz * c0 / (c1 & 0x1f) / (1 << (c1 >> 5))
  * newer one uses clock[0] and
  *     freq = 15Mhz * c0 / ((c1 & 0x1f) + 2) / (1 << (c1 >> 5))
  */
 static void
 platinumfb_set_clock(struct platinumfb_softc *sc)
 {
     uint8_t clk_idx = sc->sc_dac_type == PLATINUM_DAC_1 ? 1 : 0;
     uint8_t d2;

     platinumfb_store_d2(sc, 6, 0xc6);

     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, 3+32);
     d2 = platinumfb_read_cmap_reg(sc, PLATINUM_CMAP_D2_OFFSET);

     if (d2 == 2) {
 	platinumfb_store_d2(sc, 7, sc->sc_pfs->clock_params[clk_idx][0]);
 	platinumfb_store_d2(sc, 8, sc->sc_pfs->clock_params[clk_idx][1]);
 	platinumfb_store_d2(sc, 3, 3);
     } else {
 	platinumfb_store_d2(sc, 4, sc->sc_pfs->clock_params[clk_idx][0]);
 	platinumfb_store_d2(sc, 5, sc->sc_pfs->clock_params[clk_idx][1]);
 	platinumfb_store_d2(sc, 3, 2);
     }

     delay(5000);
     platinumfb_store_d2(sc, 9, 0xa6);
 }

 static void
 platinumfb_dac_type(struct platinumfb_softc *sc)
 {
     uint8_t dtype = 0;

     platinumfb_write_cmap_reg(sc, PLATINUM_CMAP_ADDR_OFFSET, 0x40);
     dtype = platinumfb_read_cmap_reg(sc, PLATINUM_CMAP_D2_OFFSET);

     switch (dtype) {
     case PLATINUM_DAC_0:
     case PLATINUM_DAC_1:
 	/* do nothing */
 	break;
     default:
 	aprint_error_dev(sc->sc_dev, "unknown dac 0x%x, using 0x%x\n",
 			 dtype, PLATINUM_DAC_0);
 	dtype = PLATINUM_DAC_0;
 	break;
     }

     /* save type */
     sc->sc_dac_type = dtype;
 }

 static void
 platinumfb_memory_size(struct platinumfb_softc *sc)
 {
     int i;
     off_t offset = PLATINUM_FB_BANK_SIZE;
     paddr_t total_vram = PLATINUM_FB_MIN_SIZE;

     uint8_t test_val[] = {0x34, 0x56, 0x78};
     uint8_t bank[] = {0, 0, 0};
     uint8_t num_elems = sizeof(test_val)/sizeof(test_val[0]);

     volatile uint8_t *fbuffer = mapiodev((paddr_t)sc->sc_fb, sc->sc_fb_size, false);

     if (fbuffer == NULL)
 	panic("platinumfb could not mapiodev");

     /* turn on all banks of RAM */
     platinumfb_write_reg(sc, 16, (paddr_t)sc->sc_fb);
     platinumfb_write_reg(sc, 20, 0x1011);
     platinumfb_write_reg(sc, 24, 0);

     /*
      * write "unique" value to each bank of memory and read value
      * back. if match assumes VRAM bank exists.  On the powermac 7200,
      * bank0 is always there and soldered to motherboard, don't know
      * if that is the case for others
      */
     for (i = 0 ; i < num_elems; i++) {
 	out8(fbuffer + offset, test_val[i]);
 	out8(fbuffer + offset + 0x8, 0x0);

 	__asm volatile ("eieio; dcbf 0,%0"::"r"(&fbuffer[offset]):"memory");

 	bank[i] = fbuffer[offset] == test_val[i];
 	total_vram += bank[i] * PLATINUM_FB_BANK_SIZE;
 	offset += PLATINUM_FB_BANK_SIZE;
     }

     /* save total vram or minimum */
     if (total_vram >= PLATINUM_FB_MIN_SIZE && total_vram <= PLATINUM_FB_MAX_SIZE) {
 	sc->sc_vram = total_vram;
     } else {
 	aprint_error_dev(sc->sc_dev,
 			 "invalid VRAM size 0x%lx, using min 0x%x\n",
 			 total_vram, PLATINUM_FB_MIN_SIZE);
 	sc->sc_vram = PLATINUM_FB_MIN_SIZE;
     }

     unmapiodev((paddr_t)fbuffer, sc->sc_fb_size);
 }

 static int
 platinumfb_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct confargs *ca = aux;

 	return (strcmp(ca->ca_name, "platinum") == 0);
 }

 static void
 platinumfb_attach(device_t parent, device_t self, void *aux)
 {
 	struct platinumfb_softc *sc = device_private(self);
 	struct confargs *ca = aux;
 	u_int *reg = ca->ca_reg;

 	sc->sc_dev = self;
 	sc->sc_node = ca->ca_node;

 	sc->sc_reg = (uint8_t *)reg[0];
 	sc->sc_reg_size = reg[1];

 	sc->sc_fb = (uint8_t *)reg[2];
 	sc->sc_fb_size = PLATINUM_FB_MAX_SIZE;

 	sc->sc_cmap = (uint8_t *)PLATINUM_CMAP_BASE_ADDR;
 	sc->sc_cmap_size = PLATINUM_CMAP_SIZE;

 	aprint_normal(" reg-addr 0x%08lx fb-addr 0x%08lx cmap-addr 0x%08lx\n",
 		      (paddr_t)sc->sc_reg, 
 		      (paddr_t)sc->sc_fb,
 		      (paddr_t)sc->sc_cmap);

 	config_finalize_register(sc->sc_dev, platinumfb_init);
 }

 static void
 platinumfb_init_cmap(struct platinumfb_softc *sc)
 {
     int i;
     uint8_t tmp;

     switch (sc->sc_cmode) {
     case PLATINUM_CMODE_8:
     default:
 	/* R3G3B2 colormap */
 	for (i = 0; i < 256; i++) {
 	    tmp = i & 0xe0;
 	    /*
 	     * replicate bits so 0xe0 maps to a red value of 0xff
 	     * in order to make white look actually white
 	     */
 	    tmp |= (tmp >> 3) | (tmp >> 6);
 	    sc->sc_cmap_red[i] = tmp;

 	    tmp = (i & 0x1c) << 3;
 	    tmp |= (tmp >> 3) | (tmp >> 6);
 	    sc->sc_cmap_green[i] = tmp;

 	    tmp = (i & 0x03) << 6;
 	    tmp |= tmp >> 2;
 	    tmp |= tmp >> 4;
 	    sc->sc_cmap_blue[i] = tmp;
 	}
 	break;

     case PLATINUM_CMODE_16:
 	for (i = 0; i < 32; i++) {
 	    tmp = 255 * i / 32;
 	    sc->sc_cmap_red[i] = tmp;
 	    sc->sc_cmap_green[i] = tmp;
 	    sc->sc_cmap_blue[i] = tmp;
 	}
 	for (i = 32; i < 256; i++) {
 	    sc->sc_cmap_red[i] =  0;
 	    sc->sc_cmap_blue[i] = 0;
 	    sc->sc_cmap_green[i] = 0;
 	}
 	break;

     case PLATINUM_CMODE_32:
 	for (i = 0; i < 256; i++) {
 	    sc->sc_cmap_red[i] = i;
 	    sc->sc_cmap_green[i] = i;
 	    sc->sc_cmap_blue[i] = i;
 	}
 	break;
     }
 }

 static void
 platinumfb_restore_palette(struct platinumfb_softc *sc)
 {
     int i;
     for (i = 0; i < 256; i++) {
 	platinumfb_putpalreg(sc, i, sc->sc_cmap_red[i],
 			     sc->sc_cmap_green[i], sc->sc_cmap_blue[i]);
     }
 }

 static int
 platinumfb_init(device_t self)
 {
 	struct platinumfb_softc *sc = device_private(self);
 	const struct videomode *mode = NULL;
 	struct rasops_info *ri;

 	struct wsemuldisplaydev_attach_args aa;
 	bool is_console = FALSE;
 	long defattr;

 	int i;

 	/*
 	 * become console if OF variable "output-device" is "screen" or
 	 * contains "platinum", since normal OF video variables are unavailable
 	 */
 	int options;
 	char output_device[128];
 	options = OF_finddevice("/options");
 	if (options == 0 || 
 	    options == -1 ||
 	    OF_getprop(options, "output-device", output_device, sizeof(output_device)) == 0 ) {
 	    aprint_error_dev(sc->sc_dev, "could not get output-device prop, assuming not console\n");
 	}
 	else {
 	    if (strstr(output_device,"platinum") ||
 		strcmp(output_device,"screen") == 0 ) {
 		is_console = TRUE;
 	    }
 	}	

 	sc->sc_pfs = NULL;
 	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
 	sc->sc_on = WSDISPLAYIO_VIDEO_ON;

 	/* determine vram memory and dac clock type */
 	platinumfb_memory_size(sc);
 	platinumfb_dac_type(sc);

 	aprint_normal_dev(sc->sc_dev,"is_console %d dac 0x%x vram 0x%x\n",
 			  is_console, sc->sc_dac_type, sc->sc_vram);

 	for (i=0; i < sizeof(pfb_setting)/sizeof(pfb_setting[0]); i++)
 	{
 	    if (strcmp(PLATINUM_FB_VMODE, pfb_setting[i]->vmode_name)==0) {
 		mode = pick_mode_by_ref(pfb_setting[i]->width, 
 					pfb_setting[i]->height,
 					pfb_setting[i]->freq);
 		break;
 	    }
 	}

 	if (!mode) {
 	    aprint_error_dev(sc->sc_dev, "pick_mode_by_ref failed, using default\n");
 	    mode = pick_mode_by_ref(800, 600, 75);
 	}

 	if (platinumfb_set_mode(sc, mode, PLATINUM_CONSOLE_DEPTH) != 0) {
 	    aprint_error_dev(sc->sc_dev, "platinumfb_set_mode failed\n");
 	    return 0;
 	}

 	vcons_init(&sc->vd, sc, &platinumfb_defaultscreen,
 		   &platinumfb_accessops);
 	sc->vd.init_screen = platinumfb_init_screen;

 	ri = &platinumfb_console_screen.scr_ri;
 	vcons_init_screen(&sc->vd, &platinumfb_console_screen, 1, &defattr);

 	platinumfb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;

 	platinumfb_defaultscreen.textops = &ri->ri_ops;
 	platinumfb_defaultscreen.capabilities = ri->ri_caps;
 	platinumfb_defaultscreen.nrows = ri->ri_rows;
 	platinumfb_defaultscreen.ncols = ri->ri_cols;

 	if (is_console) {
 		wsdisplay_cnattach(&platinumfb_defaultscreen, ri, 0, 0,
 		    defattr);
 		vcons_replay_msgbuf(&platinumfb_console_screen);
 	}

 	aa.console = is_console;
 	aa.scrdata = &platinumfb_screenlist;
 	aa.accessops = &platinumfb_accessops;
 	aa.accesscookie = &sc->vd;

 	config_found(self, &aa, wsemuldisplaydevprint);

 	return 0;
 }

 static void
 platinumfb_set_hardware(struct platinumfb_softc *sc)
 {
     int i;
     bool one_bank = sc->sc_vram == PLATINUM_FB_BANK_SIZE;

     /* now start programming the chip */
     platinumfb_write_reg(sc, 24, 7);    /* turn off display */

     for (i = 0; i < 26; ++i)
 	platinumfb_write_reg(sc, i+32, sc->sc_pfs->regs[i]);

     platinumfb_write_reg(sc, 26+32, one_bank ? 
 			 sc->sc_pfs->offset[sc->sc_cmode] + 4 - sc->sc_cmode :
 			 sc->sc_pfs->offset[sc->sc_cmode]);

     /*
      * reg 16 apparently needs an address 0x10 less the where frame
      * buffer/ri_bits start for console text to be aligned.  In
      * addition, X memory maps (mmap) the frame buffer starting on
      * page boundaries.  So to get both X and console text aligned we
      * start at the first page up from sc_fb[0]. Starting at sc_fb[0]
      * did work on my machine but not sure if this negative offset
      * would be problematic elsewhere.
      *
      * Not sure why linux used different fb offsets for each mode, as
      * any addresses seemed to work as long as relative difference was
      * 0x10.
      */
     platinumfb_write_reg(sc, 16, platinumfb_page_align_up(sc) - 0x10);

     platinumfb_write_reg(sc, 18, sc->sc_pfs->pitch[sc->sc_cmode]);

     /* 
      * XXX register 19 setting looks wrong for 1 bank & 32 bpp.
      * 512x384 is only resolution that would use such a setting, but
      * that is not currently in videomodes.c
      */
     if (sc->sc_cmode == PLATINUM_CMODE_32 &&
 	(sc->sc_pfs->macmode == 1 || sc->sc_pfs->macmode == 2))
 	aprint_error_dev(sc->sc_dev, "platinumfb reg19 array out-of-bounds");

     platinumfb_write_reg(sc, 19, one_bank ? 
 			 sc->sc_pfs->mode[sc->sc_cmode+1] : /* XXX fix this for 32 bpp */
 			 sc->sc_pfs->mode[sc->sc_cmode]);

     platinumfb_write_reg(sc, 20, one_bank ? 0x11 : 0x1011);
     platinumfb_write_reg(sc, 21, 0x100);
     platinumfb_write_reg(sc, 22, 1);
     platinumfb_write_reg(sc, 23, 1);
     platinumfb_write_reg(sc, 26, 0xc00);
     platinumfb_write_reg(sc, 27, 0x235);
     /* platinumfb_write_reg(sc, 27, 0x2aa); */

     platinumfb_store_d2(sc, 0, one_bank ? sc->sc_pfs->dacula_ctrl[sc->sc_cmode] & 0xf :
                                           sc->sc_pfs->dacula_ctrl[sc->sc_cmode]);
     platinumfb_store_d2(sc, 1, 4);
     platinumfb_store_d2(sc, 2, 0);

     platinumfb_set_clock(sc);

     platinumfb_write_reg(sc, 24, 0);  /* turn display on */
 }

 static int
 platinumfb_set_mode(struct platinumfb_softc *sc,
     const struct videomode *mode, int depth)
 {
 	int i;

 	/* first find the parameter for the mode register */
 	i = 0;
 	while((i < __arraycount(pfb_setting)) &&
 	      (strcmp(mode->name, pfb_setting[i]->vmode_name) != 0))
 	    i++;

 	if (i >= __arraycount(pfb_setting)) {
 		aprint_error_dev(sc->sc_dev,
 		    "Can't find a mode register value for %s\n", 
 				 mode->name);
 		return EINVAL;
 	}

 	/* found a mode */
 	sc->sc_pfs = pfb_setting[i];

 	/* determine depth settings */
 	switch (depth) {
 	case 8:
 	default:
 	    sc->sc_depth = 8;
 	    sc->sc_cmode = PLATINUM_CMODE_8;
 	    break;
 	case 15:
 	case 16:
 	    /* 15 bpp but use 16 so X/wsfb works */
 	    sc->sc_depth = 16;
 	    sc->sc_cmode = PLATINUM_CMODE_16;
 	    break;
 	case 24:
 	case 32:
 	    /* 24 bpp but use 32 so X/wsfb works */
 	    sc->sc_depth = 32;
 	    sc->sc_cmode = PLATINUM_CMODE_32;
 	    break;
 	}

 	sc->sc_modereg = sc->sc_pfs->macmode;
 	sc->sc_videomode = mode;
 	sc->sc_height = mode->vdisplay;
 	sc->sc_width = mode->hdisplay;
 	sc->sc_linebytes = sc->sc_width * (1 << sc->sc_cmode) + platinumfb_line_tweak(sc);

 	/* check if we have enough video memory */
 	if (sc->sc_height * sc->sc_linebytes > sc->sc_vram - PAGE_SIZE) {
 	    aprint_error_dev(sc->sc_dev, "Not enough video RAM for %s\n",
 			     mode->name);
 	    return EINVAL;
 	}

 	/* set up and write colormap */
 	platinumfb_init_cmap(sc);
 	platinumfb_restore_palette(sc);

 	/* set hardware registers */
 	platinumfb_set_hardware(sc);

 	aprint_normal_dev(sc->sc_dev, "switched to %s in %d bit color\n",
 			  sc->sc_pfs->vmode_name, sc->sc_depth);
 	return 0;
 }

 static int
 platinumfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
 	struct lwp *l)
 {
         struct vcons_data *vd = v;
         struct platinumfb_softc *sc = vd->cookie;
         struct wsdisplay_fbinfo *wdf;
         struct vcons_screen *ms = vd->active;
 	int i;

         switch (cmd) {
         case WSDISPLAYIO_GTYPE:
                 *(u_int *)data = WSDISPLAY_TYPE_PLATINUM;
                 return 0;

         case WSDISPLAYIO_GINFO:
                 wdf = (void *)data;
                 wdf->height = ms->scr_ri.ri_height;
                 wdf->width = ms->scr_ri.ri_width;
                 wdf->depth = ms->scr_ri.ri_depth;
                 wdf->cmsize = 256;
                 return 0;

         case WSDISPLAYIO_GVIDEO:
                 *(int *)data = sc->sc_on;
                 return 0;

         case WSDISPLAYIO_SVIDEO:
 		/* 
 		 * poor man's screen blanking, just write zeros to colormap
 		 * registers but don't save in softc.  
 		 */
                 if (*(int *)data != sc->sc_on) {
                     sc->sc_on = (sc->sc_on == WSDISPLAYIO_VIDEO_ON ?
 				 WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON);

 		    /* XXX need to lock colormap? */
                     if (sc->sc_on == WSDISPLAYIO_VIDEO_OFF)
                         for (i=0; i < 256; i++)
                             platinumfb_putpalreg(sc, i, 0, 0, 0);
                     else
 			platinumfb_restore_palette(sc);
                 }
                 return 0;

         case WSDISPLAYIO_GETCMAP:
 	        if (sc->sc_cmode == PLATINUM_CMODE_8)
 		    return platinumfb_getcmap(sc, (struct wsdisplay_cmap *)data);
 		else
 		    return 0;

         case WSDISPLAYIO_PUTCMAP:
 	        if (sc->sc_cmode == PLATINUM_CMODE_8)
 		    return platinumfb_putcmap(sc, (struct wsdisplay_cmap *)data);
 		else
 		    return 0;

         case WSDISPLAYIO_SMODE: {
 	  int new_mode = *(int*)data;

 	  if (new_mode != sc->sc_mode) {

 	    int new_depth = new_mode == WSDISPLAYIO_MODE_EMUL ?
 	      PLATINUM_CONSOLE_DEPTH : PLATINUM_FB_DEPTH;

 	    switch(new_mode) {
 	      /*
 	       * XXX - not sure how this is supposed to work for
 	       * switching bpp between console and X, but cases with
 	       * (EMUL MAPPED) or (EMUL MAPPED DUMBFB) work, but 
 	       * (EMUL DUMBFB) garbles screen for some reason.
 	       */
 	    case WSDISPLAYIO_MODE_EMUL:
 	    case WSDISPLAYIO_MODE_MAPPED:
 	    /* case WSDISPLAYIO_MODE_DUMBFB: XXX */

 	      /* in case screen is "blanked" */
 	      platinumfb_restore_palette(sc);

 	      sc->sc_mode = new_mode;

 	      platinumfb_set_mode(sc, sc->sc_videomode, new_depth);
 	      platinumfb_set_rasops(sc, &ms->scr_ri, true);

 	      if (new_mode == WSDISPLAYIO_MODE_EMUL)
 		vcons_redraw_screen(ms);
 	    }
 	  }

 	  return 0;
 	}

 	case WSDISPLAYIO_LINEBYTES:
 	        *(u_int *)data = sc->sc_linebytes;
 		return 0;

 	case WSDISPLAYIO_GET_FBINFO: {
 	    struct wsdisplayio_fbinfo *fbi = data;
 	    return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
 	}

 	}
 	return EPASSTHROUGH;
 }

 static paddr_t
 platinumfb_mmap(void *v, void *vs, off_t offset, int prot)
 {
 	struct vcons_data *vd = v;
 	struct platinumfb_softc *sc = vd->cookie;
 	paddr_t pa = -1;
 	paddr_t fb_aligned = platinumfb_page_align_up(sc);
 	paddr_t fb_vram = sc->sc_vram - (fb_aligned - (paddr_t)sc->sc_fb);

 	/* XXX need to worry about superuser or mapping other registers? */

 	if (offset >= 0 && offset < fb_vram)
 	    pa = fb_aligned + offset;

 	return pa;
 }

 static void platinumfb_set_rasops(struct platinumfb_softc *sc,
 				  struct rasops_info *ri,
 				  int existing)
 {
 	memset(ri, 0, sizeof(struct rasops_info));

 	ri->ri_depth = sc->sc_depth;
 	ri->ri_width = sc->sc_width;
 	ri->ri_height = sc->sc_height;
 	ri->ri_stride = sc->sc_linebytes;
 	ri->ri_bits = (u_char*)platinumfb_page_align_up(sc);
 	ri->ri_flg = RI_FULLCLEAR;

 	if (existing)
 	    ri->ri_flg |= RI_CLEAR;

 	switch (sc->sc_cmode) {
 	case PLATINUM_CMODE_8:
 	default:
 	    ri->ri_flg |= RI_ENABLE_ALPHA | RI_8BIT_IS_RGB;

 	    break;
 	case PLATINUM_CMODE_16:
 	    if ( strcmp(sc->sc_pfs->vmode_name, "640x480x60") == 0 ||
 		 strcmp(sc->sc_pfs->vmode_name, "800x600x75") == 0 )
 		ri->ri_flg |= RI_ENABLE_ALPHA;

 	    ri->ri_rnum = 5;
 	    ri->ri_rpos = 10;
 	    ri->ri_gnum = 5;
 	    ri->ri_gpos = 5;
 	    ri->ri_bnum = 5;
 	    ri->ri_bpos = 0;

 	    break;
 	case PLATINUM_CMODE_32:
 	    if ( strcmp(sc->sc_pfs->vmode_name, "640x480x60") == 0 ||
 		 strcmp(sc->sc_pfs->vmode_name, "800x600x75") == 0 )
 		ri->ri_flg |= RI_ENABLE_ALPHA;

 	    ri->ri_rnum = 8;
 	    ri->ri_rpos = 16;
 	    ri->ri_gnum = 8;
 	    ri->ri_gpos = 8;
 	    ri->ri_bnum = 8;
 	    ri->ri_bpos = 0;

 	    break;
 	}

 	rasops_init(ri, 0, 0);
 	ri->ri_caps = WSSCREEN_WSCOLORS;

 	rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
 		    sc->sc_width / ri->ri_font->fontwidth);

 }

 static void
 platinumfb_init_screen(void *cookie, struct vcons_screen *scr,
     int existing, long *defattr)
 {
 	struct platinumfb_softc *sc = cookie;
 	struct rasops_info *ri = &scr->scr_ri;

 	scr->scr_flags |= VCONS_DONT_READ;

 	platinumfb_set_rasops(sc, ri, existing);

 	ri->ri_hw = scr;
 }

 static int
 platinumfb_putcmap(struct platinumfb_softc *sc, struct wsdisplay_cmap *cm)
 {
 	u_char *r, *g, *b;
 	u_int index = cm->index;
 	u_int count = cm->count;
 	int i, error;
 	u_char rbuf[256], gbuf[256], bbuf[256];

 	if (cm->index >= 256 || cm->count > 256 ||
 	    (cm->index + cm->count) > 256)
 		return EINVAL;
 	error = copyin(cm->red, &rbuf[index], count);
 	if (error)
 		return error;
 	error = copyin(cm->green, &gbuf[index], count);
 	if (error)
 		return error;
 	error = copyin(cm->blue, &bbuf[index], count);
 	if (error)
 		return error;

 	memcpy(&sc->sc_cmap_red[index], &rbuf[index], count);
 	memcpy(&sc->sc_cmap_green[index], &gbuf[index], count);
 	memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count);

 	/* write colormap registers if not currently blanked */
 	if (sc->sc_on == WSDISPLAYIO_VIDEO_ON) {
 	    r = &sc->sc_cmap_red[index];
 	    g = &sc->sc_cmap_green[index];
 	    b = &sc->sc_cmap_blue[index];

 	    for (i = 0; i < count; i++) {
 		platinumfb_putpalreg(sc, index, *r, *g, *b);
 		index++;
 		r++, g++, b++;
 	    }
 	}

 	return 0;
 }

 static int
 platinumfb_getcmap(struct platinumfb_softc *sc, struct wsdisplay_cmap *cm)
 {
 	u_int index = cm->index;
 	u_int count = cm->count;
 	int error;

 	if (index >= 255 || count > 256 || index + count > 256)
 		return EINVAL;

 	error = copyout(&sc->sc_cmap_red[index],   cm->red,   count);
 	if (error)
 		return error;
 	error = copyout(&sc->sc_cmap_green[index], cm->green, count);
 	if (error)
 		return error;
 	error = copyout(&sc->sc_cmap_blue[index],  cm->blue,  count);
 	if (error)
 		return error;

 	return 0;
 }

From: scole_mail <scole_mail@gmx.com>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: port-macppc/48600
Date: Wed, 27 Apr 2016 08:39:27 -0400

 Any chance the rest of this can be checked in?  These changes are
 starting to become foggy in my mind. I can resubmit patches vs current
 if that would help.

 Also, various docs need to be updated to indicate 601 and platinum fb
 supported once the rest is checked in:
  http://www.netbsd.org/ports/macppc/models.html
  http://www.netbsd.org/ports/macppc/faq.html
  macppc INSTALL document
  add platinum fb video man page
  any others missing?

 Thanks

From: scole_mail@gmx.com
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: port-macppc/48600 
Date: Sat, 11 Jun 2016 13:23:46 -0400

 I am not sure, but the cmpi instructios in
 	sys/arch/macppc/stand/ofwboot/Locore.c
         sys/arch/macppc/stand/bootxx/bootxx.c
 may need to be
 	cmpi 0, 0, ..., ...
 instead of
 	cmpi 0, 1, ..., ...

 I know the "comp 0,1,..."  worked on my 601 and an old 601 manual I have
 says the 601 will ignore the L (sign extend 64bits) field.  But I just
 read in other places which say L=1 is an invalid instruction for 32
 implementations.

 I think the Locore.c patch is already checked in, but not the bootxx.c
 one.  I can resubmit patches for everything not yet checked in for the
 PR if it would be helpful.

 Thanks

State-Changed-From-To: open->closed
State-Changed-By: scole@NetBSD.org
State-Changed-When: Wed, 21 Sep 2016 12:44:07 -0700
State-Changed-Why:
I'm closing this because most of this checked in, remain items in
http://gnats.netbsd.org/51492 (rasops issue)
http://gnats.netbsd.org/51495 (601 won't boot of disk)


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.