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:
(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.