Module Name:    src
Committed By:   jmcneill
Date:           Sat Jan 20 21:36:00 UTC 2024

Modified Files:
        src/distrib/utils/embedded: mkimage
        src/etc/etc.evbppc: Makefile.inc
        src/usr.sbin/sysinst/arch/evbppc: md.c md.h
Added Files:
        src/distrib/utils/embedded/conf: evbppc.conf wii.conf
        src/distrib/utils/embedded/files: evbppc_wii_meta.xml
        src/sys/arch/evbppc/conf: INSTALL_WII Makefile.wii.inc WII files.wii
            std.wii
        src/sys/arch/evbppc/include: wii.h
        src/sys/arch/evbppc/wii: autoconf.c machdep.c mainbus.c pic_pi.c
            wii_locore.S wii_mmuinit.S
        src/sys/arch/evbppc/wii/dev: ehci_hollywood.c hollywood.c hollywood.h
            mainbus.h ohci_hollywood.c resetbtn.c sdhc_hollywood.c vireg.h
            wiifb.c

Log Message:
evbppc: Add initial support for the Nintendo Wii


To generate a diff of this commit:
cvs rdiff -u -r1.78 -r1.79 src/distrib/utils/embedded/mkimage
cvs rdiff -u -r0 -r1.1 src/distrib/utils/embedded/conf/evbppc.conf \
    src/distrib/utils/embedded/conf/wii.conf
cvs rdiff -u -r0 -r1.1 src/distrib/utils/embedded/files/evbppc_wii_meta.xml
cvs rdiff -u -r1.14 -r1.15 src/etc/etc.evbppc/Makefile.inc
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbppc/conf/INSTALL_WII \
    src/sys/arch/evbppc/conf/Makefile.wii.inc src/sys/arch/evbppc/conf/WII \
    src/sys/arch/evbppc/conf/files.wii src/sys/arch/evbppc/conf/std.wii
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbppc/include/wii.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbppc/wii/autoconf.c \
    src/sys/arch/evbppc/wii/machdep.c src/sys/arch/evbppc/wii/mainbus.c \
    src/sys/arch/evbppc/wii/pic_pi.c src/sys/arch/evbppc/wii/wii_locore.S \
    src/sys/arch/evbppc/wii/wii_mmuinit.S
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbppc/wii/dev/ehci_hollywood.c \
    src/sys/arch/evbppc/wii/dev/hollywood.c \
    src/sys/arch/evbppc/wii/dev/hollywood.h \
    src/sys/arch/evbppc/wii/dev/mainbus.h \
    src/sys/arch/evbppc/wii/dev/ohci_hollywood.c \
    src/sys/arch/evbppc/wii/dev/resetbtn.c \
    src/sys/arch/evbppc/wii/dev/sdhc_hollywood.c \
    src/sys/arch/evbppc/wii/dev/vireg.h src/sys/arch/evbppc/wii/dev/wiifb.c
cvs rdiff -u -r1.10 -r1.11 src/usr.sbin/sysinst/arch/evbppc/md.c
cvs rdiff -u -r1.3 -r1.4 src/usr.sbin/sysinst/arch/evbppc/md.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/utils/embedded/mkimage
diff -u src/distrib/utils/embedded/mkimage:1.78 src/distrib/utils/embedded/mkimage:1.79
--- src/distrib/utils/embedded/mkimage:1.78	Sat Sep 25 08:54:30 2021
+++ src/distrib/utils/embedded/mkimage	Sat Jan 20 21:35:59 2024
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $NetBSD: mkimage,v 1.78 2021/09/25 08:54:30 maya Exp $
+# $NetBSD: mkimage,v 1.79 2024/01/20 21:35:59 jmcneill Exp $
 #
 # Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -312,11 +312,11 @@ else
 
 		echo ${bar} Adding label ${bar}
 		make_label > ${tmp}/label
-		${DISKLABEL} -R -F ${image} ${tmp}/label
+		${DISKLABEL} -m -R -F ${image} ${tmp}/label
 	elif [ -n "${netbsdid}" ]; then
 		echo ${bar} Adding label ${bar}
 		make_label > ${tmp}/label
-		${DISKLABEL} -R -F ${image} ${tmp}/label
+		${DISKLABEL} -m -R -F ${image} ${tmp}/label
 
 		echo ${bar} Running fdisk ${bar}
 		${FDISK} -f -i ${image}

Index: src/etc/etc.evbppc/Makefile.inc
diff -u src/etc/etc.evbppc/Makefile.inc:1.14 src/etc/etc.evbppc/Makefile.inc:1.15
--- src/etc/etc.evbppc/Makefile.inc:1.14	Fri Apr  2 07:08:36 2021
+++ src/etc/etc.evbppc/Makefile.inc	Sat Jan 20 21:35:59 2024
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.inc,v 1.14 2021/04/02 07:08:36 rin Exp $
+#	$NetBSD: Makefile.inc,v 1.15 2024/01/20 21:35:59 jmcneill Exp $
 #
 #	etc.evbppc/Makefile.inc -- evbppc-specific etc Makefile targets
 #
@@ -26,6 +26,44 @@ KERNEL_SETS+=		TWRP1025
 BUILD_KERNELS+=		INSTALL_P2020DS INSTALL_P2020RDB
 BUILD_KERNELS+=		INSTALL_RB850GX2
 BUILD_KERNELS+=		INSTALL_TWRP1025
+# wii
+KERNEL_SETS+=		WII
+BUILD_KERNELS+=		INSTALL_WII
 #
 KERNEL_SUFFIXES=	img bin ub
 .endif
+
+# Support for mkimage
+MKIMAGE= 	${NETBSDSRCDIR}/distrib/utils/embedded/mkimage
+IMAGE.rel=      ${RELEASEDIR}/${RELEASEMACHINEDIR}
+IMAGE.dir=      ${IMAGE.rel}/binary/gzimg
+IMAGE.kern=     ${IMAGE.rel}/binary/kernel
+IMAGEENDIAN=	be
+
+__mkimage: .USE
+	TOOL_MAKE=${MAKE} \
+	TOOL_MAKEFS=${TOOL_MAKEFS} \
+	TOOL_DISKLABEL=${TOOL_DISKLABEL} \
+	TOOL_FDISK=${TOOL_FDISK} \
+	TOOL_GPT=${TOOL_GPT} \
+	TOOL_GZIP=${TOOL_GZIP} \
+	TOOL_MKNOD=${TOOL_MKNOD} \
+	TOOL_PAX=${TOOL_PAX} \
+	TOOL_MKUBOOTIMAGE=${TOOL_MKUBOOTIMAGE} \
+	TOOL_MTREE=${TOOL_MTREE} \
+	HOST_SH=${HOST_SH} \
+	KERNOBJDIR=${KERNOBJDIR} \
+	MACHINE=${MACHINE} \
+	MKDTB=${MKDTB} \
+	${HOST_SH} -x ${MKIMAGE} -h ${.TARGET:S/smp_//} -D ${DESTDIR} \
+            -S ${NETBSDSRCDIR} -B ${IMAGEENDIAN} ${MKI_OPTS.${.TARGET}} \
+            ${IMAGE.dir}/${.TARGET:S/smp_//}.img.gz
+
+.if ${MACHINE_ARCH} == "powerpc"
+smp_wii: __mkimage
+MKI_OPTS.smp_wii=	-K ${IMAGE.kern}
+SNAP_MD_POST_DEPS+=	smp_wii
+INSTALLATION_DIRS+=	binary/gzimg
+.endif
+
+snap_md_post: check_DESTDIR check_RELEASEDIR snap_post .WAIT ${SNAP_MD_POST_DEPS}

Index: src/usr.sbin/sysinst/arch/evbppc/md.c
diff -u src/usr.sbin/sysinst/arch/evbppc/md.c:1.10 src/usr.sbin/sysinst/arch/evbppc/md.c:1.11
--- src/usr.sbin/sysinst/arch/evbppc/md.c:1.10	Sat Jan 29 16:01:18 2022
+++ src/usr.sbin/sysinst/arch/evbppc/md.c	Sat Jan 20 21:36:00 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: md.c,v 1.10 2022/01/29 16:01:18 martin Exp $ */
+/*	$NetBSD: md.c,v 1.11 2024/01/20 21:36:00 jmcneill Exp $ */
 
 /*
  * Copyright 1997,2002 Piermont Information Systems Inc.
@@ -36,6 +36,7 @@
 
 #include <sys/param.h>
 #include <sys/sysctl.h>
+#include <sys/utsname.h>
 #include <stdio.h>
 #include <util.h>
 
@@ -52,7 +53,19 @@ md_init(void)
 void
 md_init_set_status(int flags)
 {
+	struct utsname instsys;
+
 	(void)flags;
+
+	/*
+	 * Get the name of the install kernel we are running under and
+	 * enable the installation of the corresponding kernel.
+	 */
+	uname(&instsys);
+	if (strstr(instsys.version, "(INSTALL_WII")) {
+		set_kernel_set(EVBPPC_SET_KERNEL_WII);
+		set_noextract_set(EVBPPC_SET_KERNEL_WII);
+	}
 }
 
 bool

Index: src/usr.sbin/sysinst/arch/evbppc/md.h
diff -u src/usr.sbin/sysinst/arch/evbppc/md.h:1.3 src/usr.sbin/sysinst/arch/evbppc/md.h:1.4
--- src/usr.sbin/sysinst/arch/evbppc/md.h:1.3	Wed Oct  2 11:16:02 2019
+++ src/usr.sbin/sysinst/arch/evbppc/md.h	Sat Jan 20 21:36:00 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: md.h,v 1.3 2019/10/02 11:16:02 maya Exp $	*/
+/*	$NetBSD: md.h,v 1.4 2024/01/20 21:36:00 jmcneill Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -53,6 +53,8 @@
  *      base etc comp games man misc rescue tests text xbase xcomp xetc xfont xserver
  */
 #define SET_KERNEL_1_NAME	"kern-GENERIC"
+#define SET_KERNEL_2_NAME	"kern-WII"
+#define EVBPPC_SET_KERNEL_WII	SET_KERNEL_2
 
 /*
  * Machine-specific command to write a new label to a disk.

Added files:

Index: src/distrib/utils/embedded/conf/evbppc.conf
diff -u /dev/null src/distrib/utils/embedded/conf/evbppc.conf:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/distrib/utils/embedded/conf/evbppc.conf	Sat Jan 20 21:35:59 2024
@@ -0,0 +1,195 @@
+# $NetBSD: evbppc.conf,v 1.1 2024/01/20 21:35:59 jmcneill Exp $ */
+# evbppc shared config
+#
+image=$HOME/${board}.img
+
+MACHINE=evbppc
+
+extra=48		# spare space
+init=32
+boot=$((192 - ${init}))
+ffsoffset=$(( (${init} + ${boot}) / 2 ))m
+
+size=0		# autocompute
+msdosid=12
+
+if $gpt; then
+	partition_type="gpt"
+else
+	partition_type="disklabel"
+fi
+
+mkdir -p ${mnt}/boot
+
+make_label_evbppc() {
+	# compute all sizes in terms of sectors
+	local totalsize=$(( ${size} / 512 ))
+
+	local bootsize=$(( ${boot} * 1024 ))
+
+	local bootoffset=$(( ${init} * 1024 ))
+
+	local asize=$(( ${totalsize} - ${bootsize} - ${bootoffset} ))
+	local aoffset=$(( ${bootoffset} + ${bootsize} ))
+
+	local bps=512
+	local spt=32
+	local tpc=64
+	local spc=2048
+	local cylinders=$(( ${totalsize} / ${spc} ))
+
+	cat << EOF
+type: SCSI
+disk: STORAGE DEVICE
+label: fictitious
+flags: removable
+bytes/sector: ${bps}
+sectors/track: ${spt}
+tracks/cylinder: ${tpc}
+sectors/cylinder: ${spc}
+cylinders: ${cylinders}
+total sectors: ${totalsize}
+rpm: 3600
+interleave: 1
+trackskew: 0
+cylinderskew: 0
+headswitch: 0           # microseconds
+track-to-track seek: 0  # microseconds
+drivedata: 0 
+
+8 partitions:
+#     size         offset        fstype [fsize bsize cpg/sgs]
+ a:   ${asize}     ${aoffset}    4.2BSD  ${fsize} ${bsize} 0  # 
+ c:   ${totalsize} 0             unused      0     0          #
+ e:   ${bootsize}  ${bootoffset} MSDOS                        #
+EOF
+}
+
+make_fstab_evbppc_gpt() {
+	cat > ${mnt}/etc/fstab << EOF
+# NetBSD /etc/fstab
+# See /usr/share/examples/fstab/ for more examples.
+NAME=${gpt_label_ffs:-netbsd-root}	/		ffs	rw,noatime	1 1
+NAME=${gpt_label_boot:-boot}		/boot		msdos	rw	1 1
+ptyfs		/dev/pts	ptyfs	rw
+procfs		/proc		procfs	rw
+tmpfs		/var/shm	tmpfs	rw,-m1777,-sram%25
+EOF
+}
+
+make_fstab_evbppc_normal() {
+	cat > ${mnt}/etc/fstab << EOF
+# NetBSD /etc/fstab
+# See /usr/share/examples/fstab/ for more examples.
+ROOT.a		/		ffs	rw,noatime	1 1
+ROOT.e		/boot		msdos	rw	1 1
+ptyfs		/dev/pts	ptyfs	rw
+procfs		/proc		procfs	rw
+tmpfs		/var/shm	tmpfs	rw,-m1777,-sram%25
+EOF
+}
+
+# From Richard Neswold's:
+# http://rich-tbp.blogspot.com/2013/03/netbsd-on-rpi-minimizing-disk-writes.html
+# Also for the postfix stuff below
+make_fstab_evbppc_minwrites() {
+	cat > ${mnt}/etc/fstab << EOF
+# NetBSD /etc/fstab
+# See /usr/share/examples/fstab/ for more examples.
+ROOT.a		/			ffs	rw,log,noatime,nodevmtime 1 1
+ROOT.e		/boot			msdos	rw			  1 1
+ptyfs		/dev/pts		ptyfs	rw
+procfs		/proc			procfs	rw
+tmpfs		/tmp			tmpfs	rw,-s32M
+tmpfs		/var/log		tmpfs	rw,union,-s32M
+tmpfs		/var/run		tmpfs	rw,union,-s1M
+tmpfs		/var/mail		tmpfs	rw,union,-s10M
+tmpfs		/var/spool/postfix	tmpfs	rw,union,-s20M
+tmpfs		/var/db/postfix		tmpfs	rw,union,-s1M
+tmpfs		/var/chroot		tmpfs	rw,union,-s10M
+tmpfs		/var/shm		tmpfs	rw,-m1777,-sram%25
+EOF
+}
+
+make_fstab_evbppc() {
+	if $gpt; then
+		make_fstab_evbppc_gpt
+	elif $minwrites; then
+		make_fstab_evbppc_minwrites
+	else
+		make_fstab_evbppc_normal
+	fi
+	echo "./etc/fstab type=file uname=root gname=wheel mode=0644" \
+	    >> "$tmp/selected_sets"
+
+	# Missing mount points from fstab
+	echo "./proc type=dir uname=root gname=wheel mode=0755" \
+	    >> "$tmp/selected_sets"
+}
+
+customize_evbppc() {
+	if $minwrites; then
+		mkdir ${mnt}/etc/postfix
+		(umask 022
+		sed -e 's/fifo/unix/' < ${release}/etc/postfix/master.cf > \
+		    ${mnt}/etc/postfix/master.cf)
+	fi
+	
+	cp ${release}/etc/rc.conf ${mnt}/etc/rc.conf
+	cat >> ${mnt}/etc/rc.conf << EOF
+dev_exists() {
+	if /sbin/drvctl -l \$1 >/dev/null 2>&1 ; then
+		printf YES
+	else
+		printf NO
+	fi
+}
+
+rc_configured=YES
+hostname=${hostname:-${board}}
+savecore=NO
+sshd=YES
+dhcpcd=YES
+ntpd=YES
+ntpd_flags="-g"
+creds_msdos=YES
+creds_msdos_partition=/boot
+certctl_init=YES
+EOF
+
+	if ! ${swap:-false}; then
+		cat >> ${mnt}/etc/rc.conf << EOF
+no_swap=YES
+EOF
+	fi
+	if $resize; then
+		cat >> ${mnt}/etc/rc.conf << EOF
+resize_${partition_type}=YES
+resize_root=YES
+resize_root_flags="-p"
+resize_root_postcmd="/sbin/reboot -n"
+EOF
+	fi
+
+	echo "./etc/rc.conf type=file uname=root gname=wheel mode=0644" \
+	    >> "$tmp/selected_sets"
+
+	mkdir ${mnt}/etc/rc.d
+	for _f in resize_${partition_type} creds_msdos; do
+		cp ${DIR}/files/${_f} ${mnt}/etc/rc.d/${_f}
+		echo "./etc/rc.d/${_f} type=file uname=root gname=wheel mode=0555" \
+		    >> "$tmp/selected_sets"
+	done
+
+	if [ ! -f ${release}/dev/MAKEDEV ]; then
+		echo ${PROG}: Missing ${release}/dev/MAKEDEV 1>&2
+		exit 1
+	fi
+	echo "${bar} running MAKEDEV ${bar}"
+	${HOST_SH} ${release}/dev/MAKEDEV -s all | sed -e 's:^\./:\./dev/:' \
+	    >> "$tmp/selected_sets"
+
+	echo "${bar} fixing up permissions"
+	echo "./boot type=dir uname=root gname=wheel mode=0755" \
+	    >> "$tmp/selected_sets"
+}
Index: src/distrib/utils/embedded/conf/wii.conf
diff -u /dev/null src/distrib/utils/embedded/conf/wii.conf:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/distrib/utils/embedded/conf/wii.conf	Sat Jan 20 21:35:59 2024
@@ -0,0 +1,62 @@
+# $NetBSD: wii.conf,v 1.1 2024/01/20 21:35:59 jmcneill Exp $
+# Nintendo Wii customization script used by mkimage
+#
+board=wii
+resize=true
+swap=true
+swap_size_MB=128
+swap_file=/swap
+
+. ${DIR}/conf/evbppc.conf
+
+kernel_WII="WII"
+
+make_label() {
+	make_label_evbppc
+}
+
+make_fstab() {
+	make_fstab_evbppc
+
+	cat >> ${mnt}/etc/fstab << EOF
+${swap_file} none swap sw,priority=1 0 0
+EOF
+}
+
+customize() {
+	customize_evbppc
+	cat >> "${mnt}/etc/rc.conf" << EOF
+mdnsd=YES
+devpubd=YES
+wscons=YES
+makemandb=NO
+EOF
+}
+
+populate() {
+	echo "${bar} looking for kernel in ${kernel} ${bar}"
+	k="${kernel}/netbsd-WII.gz"
+
+	# install files to /boot partition
+	tgt="apps/netbsd/boot.elf"
+	echo "${bar} installing ${k} to /boot/${tgt} ${bar}"
+	mkdir -p "${mnt}/boot/apps/netbsd"
+	case "${k}" in
+	*.gz)
+		${GZIP_CMD} -dc "${k}" > "${mnt}/boot/${tgt}"
+		;;
+	*)
+		cp "${k}" "${mnt}/boot/${tgt}"
+		;;
+	esac
+
+	# Metadata for HBC
+	cp ${DIR}/files/evbppc_wii_meta.xml ${mnt}/boot/apps/netbsd/meta.xml
+
+	# Add swap space
+	rm -f ${mnt}${swap_file}
+	dd if=/dev/zero of=${mnt}${swap_file} bs=1 count=0 \
+	    seek=$((${swap_size_MB} * 1024 * 1024))
+	echo ".${swap_file} type=file uname=root gname=wheel mode=0600" \
+            >> "$tmp/selected_sets"
+}

Index: src/distrib/utils/embedded/files/evbppc_wii_meta.xml
diff -u /dev/null src/distrib/utils/embedded/files/evbppc_wii_meta.xml:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/distrib/utils/embedded/files/evbppc_wii_meta.xml	Sat Jan 20 21:35:59 2024
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<app version="1">
+  <name>NetBSD</name>
+  <author>https://www.NetBSD.org</author>
+  <version></version>
+  <release_date></release_date>
+  <short_description>Free Unix-like operating system.</short_description>
+  <long_description>NetBSD is a free, fast, secure, and highly portable Unix-like Open Source operating system.</long_description>
+  <ahb_access/>
+</app>

Index: src/sys/arch/evbppc/conf/INSTALL_WII
diff -u /dev/null src/sys/arch/evbppc/conf/INSTALL_WII:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/conf/INSTALL_WII	Sat Jan 20 21:35:59 2024
@@ -0,0 +1,7 @@
+# 	$NetBSD: INSTALL_WII,v 1.1 2024/01/20 21:35:59 jmcneill Exp $
+
+include "arch/evbppc/conf/WII"
+
+#ident 		"INSTALL_WII-$Revision: 1.1 $"
+
+include "arch/evbppc/conf/INSTALL.inc"
Index: src/sys/arch/evbppc/conf/Makefile.wii.inc
diff -u /dev/null src/sys/arch/evbppc/conf/Makefile.wii.inc:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/conf/Makefile.wii.inc	Sat Jan 20 21:35:59 2024
@@ -0,0 +1,17 @@
+#	$NetBSD: Makefile.wii.inc,v 1.1 2024/01/20 21:35:59 jmcneill Exp $
+
+CFLAGS+=-mcpu=750
+AFLAGS+=-mcpu=750
+
+.ifndef TEXTADDR
+BEGIN:
+	echo "TEXTADDR not defined in kernel config!"
+	exit 1
+.endif
+
+SYSTEM_FIRST_OBJ=	${BOARDTYPE}_locore.o
+SYSTEM_FIRST_SFILE=	${THISPPC}/${BOARDTYPE}/${BOARDTYPE}_locore.S
+
+SYSTEM_LD_TAIL= \
+	mv $@ $@_${TEXTADDR}.elf ; \
+	${OBJCOPY} --adjust-vma 0x80000000 $@_${TEXTADDR}.elf $@
Index: src/sys/arch/evbppc/conf/WII
diff -u /dev/null src/sys/arch/evbppc/conf/WII:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/conf/WII	Sat Jan 20 21:35:59 2024
@@ -0,0 +1,200 @@
+#	$NetBSD: WII,v 1.1 2024/01/20 21:35:59 jmcneill Exp $
+#
+#	Nintendo Wii
+#
+
+include 	"arch/evbppc/conf/std.wii"
+
+#options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
+
+ident 		"WII"
+
+options 	MSGBUFSIZE=0x10000
+
+maxusers	32
+
+options 	INSECURE	# disable kernel security levels
+options 	NTP		# NTP phase/frequency locked loop
+options 	KTRACE		# system call tracing via ktrace(1)
+
+options 	SYSVMSG		# System V message queues
+options 	SYSVSEM		# System V semaphores
+options 	SYSVSHM		# System V shared memory
+
+options 	USERCONF	# userconf(4) support
+#options PIPE_SOCKETPAIR	# smaller, but slower pipe(2)
+#options 	SYSCTL_INCLUDE_DESCR	# Include sysctl descriptions in kernel
+
+# Alternate buffer queue strategies for better responsiveness under high
+# disk I/O load.
+#options 	BUFQ_READPRIO
+options 	BUFQ_PRIOCSCAN
+
+# Diagnostic/debugging support options
+options 	DIAGNOSTIC	# cheap kernel consistency checks
+#options 	DEBUG		# expensive debugging checks/support
+options 	DDB		# in-kernel debugger
+options 	DDB_HISTORY_SIZE=512	# enable history editing in DDB
+#options 	TRAP_PANICWAIT
+makeoptions COPY_SYMTAB=1	# size for embedded symbol table
+
+#options 	KGDB		# remote debugger
+#options 	KGDB_DEVNAME="\"com\"",KGDB_DEVADDR=0xff600400,KGDB_DEVRATE=9600
+makeoptions DEBUG="-g"	# compile full symbol table
+
+# Compatibility options
+include 	"conf/compat_netbsd50.config"
+#options 	COMPAT_386BSD_MBRPART # recognize old partition ID
+
+# File systems
+file-system 	FFS		# UFS
+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 	PROCFS		# /proc
+file-system 	TMPFS		# efficient memory file system
+file-system 	UMAPFS		# NULLFS + uid and gid remapping
+file-system 	UNION		# union file system
+file-system	PTYFS		# /dev/pts/N support
+
+# File system options
+options 	FFS_EI		# FFS Endian Independent support
+#options 	FFS_NO_SNAPSHOT	# No FFS snapshot support
+#options 	QUOTA		# legacy UFS quotas
+#options 	QUOTA2		# new, in-filesystem UFS quotas
+#options 	UFS_DIRHASH	# UFS Large Directory Hashing
+#options 	UFS_EXTATTR	# Extended attribute support for UFS1
+options 	WAPBL		# File system journaling support
+#options 	LFS_DIRHASH	# LFS version of UFS_DIRHASH - experimental
+#options 	EXT2FS_SYSTEM_FLAGS # makes ext2fs file flags (append and
+				# immutable) behave as system flags.
+options 	DISKLABEL_EI	# disklabel Endian Independent support
+#options 	NFSSERVER	# Network File System server
+
+options 	NFS_BOOT_DHCP,NFS_BOOT_BOOTPARAM
+options 	NFS_BOOT_RWSIZE=1024
+
+# Networking options
+options 	GATEWAY		# packet forwarding
+options 	INET		# IP + ICMP + TCP + UDP
+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 	TCP_DEBUG	# Record last TCP_NDEBUG packets with SO_DEBUG
+
+# These options enable verbose messages for several subsystems.
+# Warning, these may compile large string tables into the kernel!
+options 	MIIVERBOSE	# verbose PHY autoconfig messages
+#options 	SCSIVERBOSE	# human readable SCSI error messages
+options 	USBVERBOSE	# verbose USB device autoconfig messages
+
+# Kernel root file system and dump configuration.
+config		netbsd	root on ? type ?
+
+#
+# Device configuration
+#
+
+mainbus0 at root
+
+cpu0		at mainbus0
+genfb0		at mainbus0 addr 0x0c002000
+wsdisplay*      at wsemuldisplaydev?
+options 	WSEMUL_VT100
+options 	WSDISPLAY_CUSTOM_OUTPUT
+options 	WS_DEFAULT_FG=WSCOL_WHITE
+options 	WS_DEFAULT_BG=WSCOL_BLACK
+options 	WS_KERNEL_FG=WSCOL_GREEN
+options 	WS_KERNEL_BG=WSCOL_BLACK
+options 	WSDISPLAY_COMPAT_PCVT
+options 	WSDISPLAY_COMPAT_SYSCONS
+options 	WSDISPLAY_COMPAT_USL
+#options 	WSDISPLAY_COMPAT_RAWKBD
+options 	WSDISPLAY_DEFAULTSCREENS=4
+options 	WSDISPLAY_SCROLLSUPPORT
+
+hollywood0 	at mainbus0 irq 14
+
+#iosipc0 	at hollywood0 addr 0x0d000000 irq 30	# IOS IPC
+resetbtn0	at hollywood0 irq 17			# Reset button
+
+ehci0		at hollywood0 addr 0x0d040000 irq 4	# EHCI
+#ohci0		at hollywood0 addr 0x0d050000 irq 5	# OHCI0
+#ohci1		at hollywood0 addr 0x0d060000 irq 6	# OHCI1
+usb*		at usbus?
+
+sdhc0		at hollywood0 addr 0x0d070000 irq 7	# SD card
+sdhc1		at hollywood0 addr 0x0d080000 irq 8	# SDIO/BT
+sdmmc*		at sdmmcbus?
+ld*		at sdmmc?
+
+include "dev/usb/usbdevices.config"
+include "dev/bluetooth/bluetoothdevices.config"
+
+# MII/PHY support
+urlphy*		at mii? phy ?
+ukphy*		at mii? phy ?
+
+# Radio support
+radio*	at radiodev?
+
+# Audio support
+audio*	at audiobus?
+spkr*	at audio?		# PC speaker (synthesized)
+midi*	at midibus?
+pseudo-device	sequencer	# MIDI sequencer
+
+# SCSI bus support
+scsibus* at scsi? channel ?
+
+# SCSI devices
+sd*	at scsibus? target ? lun ?	# SCSI disk 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
+ses*	at scsibus? target ? lun ?	# SCSI Enclosure Services devices
+ss*	at scsibus? target ? lun ?	# SCSI scanners
+uk*	at scsibus? target ? lun ?	# SCSI unknown
+
+pseudo-device	vnd			# disk-like interface to files
+#pseudo-device	fss			# file system snapshot device
+#pseudo-device	cgd			# cryptographic disk devices
+#pseudo-device	md			# memory disk device
+pseudo-device	loop			# network loopback
+pseudo-device	bpfilter		# packet filter
+pseudo-device 	carp			# Common Address Redundancy Protocol
+pseudo-device	npf			# NPF packet filter
+pseudo-device	ppp			# Point-to-Point Protocol
+pseudo-device	sl			# Serial Line IP
+pseudo-device	tun			# network tunneling over tty
+pseudo-device	gre			# generic L3 over IP tunnel
+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	pty			# pseudo-terminals
+pseudo-device	clockctl		# user control of clock subsystem
+pseudo-device	drvctl			# user control of drive subsystem
+pseudo-device	putter			# for puffs and pud
+pseudo-device	ksyms
+
+# wscons pseudo-devices
+pseudo-device	wsmux			# mouse & keyboard multiplexor
+pseudo-device	wsfont
+options         FONT_BOLD8x16
+
+include "dev/veriexec.config"
Index: src/sys/arch/evbppc/conf/files.wii
diff -u /dev/null src/sys/arch/evbppc/conf/files.wii:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/conf/files.wii	Sat Jan 20 21:35:59 2024
@@ -0,0 +1,58 @@
+#	$NetBSD: files.wii,v 1.1 2024/01/20 21:35:59 jmcneill Exp $
+#
+#
+maxpartitions 16
+
+maxusers 2 8 64
+
+include "arch/powerpc/pic/files.pic"
+
+file	arch/evbppc/wii/autoconf.c
+file	arch/powerpc/powerpc/clock.c
+file	arch/evbppc/wii/pic_pi.c
+file	arch/evbppc/wii/machdep.c
+
+#
+# Machine-independent drivers
+#
+include "dev/ata/files.ata"
+include "dev/bluetooth/files.bluetooth"
+include "dev/scsipi/files.scsipi"
+include "dev/sdmmc/files.sdmmc"
+include "dev/usb/files.usb"
+
+#
+# Memory Disk for install floppy
+#
+file dev/md_root.c	memory_disk_hooks
+
+#
+# System bus types
+#
+define	mainbus { [addr=-1], [irq=-1] }
+device	mainbus: mainbus
+attach	mainbus at root
+device	cpu
+attach	cpu at mainbus
+file	arch/evbppc/wii/mainbus.c		mainbus | cpu	needs-flag
+
+attach	genfb at mainbus with wiifb
+file	arch/evbppc/wii/dev/wiifb.c		wiifb
+
+define	hollywood { [addr=-1], [irq=-1] }
+device	hollywood: hollywood
+attach	hollywood at mainbus
+file	arch/evbppc/wii/dev/hollywood.c		hollywood
+
+device	resetbtn
+attach	resetbtn at hollywood
+file	arch/evbppc/wii/dev/resetbtn.c		resetbtn
+
+attach	ehci at hollywood with ehci_hollywood
+file	arch/evbppc/wii/dev/ehci_hollywood.c	ehci_hollywood
+
+attach	ohci at hollywood with ohci_hollywood
+file	arch/evbppc/wii/dev/ohci_hollywood.c	ohci_hollywood
+
+attach	sdhc at hollywood with sdhc_hollywood
+file	arch/evbppc/wii/dev/sdhc_hollywood.c	sdhc_hollywood
Index: src/sys/arch/evbppc/conf/std.wii
diff -u /dev/null src/sys/arch/evbppc/conf/std.wii:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/conf/std.wii	Sat Jan 20 21:35:59 2024
@@ -0,0 +1,26 @@
+#	$NetBSD: std.wii,v 1.1 2024/01/20 21:35:59 jmcneill Exp $
+#
+# standard, required NetBSD/wii 'options'
+
+machine		evbppc powerpc
+include		"conf/std"	# MI standard options
+
+options 	PPC_OEA		# Nintendo Wii uses IBM PPC750CXe CPUs
+makeoptions 	PPCDIR="oea"	# Tell Makefile.powerpc what dir to use
+
+# Executable support:
+options 	EXEC_ELF32	# exec ELF binaries
+options 	EXEC_SCRIPT	# exec #! scripts
+options		EVBPPC_HAS_MBR
+
+options 	INTSTK=0x2000
+
+#makeoptions	TEXTADDR=0x80004000
+makeoptions	TEXTADDR=0x4000
+options 	DISTANT_KERNEL
+makeoptions 	EXTRA_LINKFLAGS="-q"
+makeoptions	BOARDTYPE="wii"
+
+options		PPC_INTR_IMPL="<powerpc/intr.h>"
+
+include		"arch/evbppc/conf/files.wii"

Index: src/sys/arch/evbppc/include/wii.h
diff -u /dev/null src/sys/arch/evbppc/include/wii.h:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/include/wii.h	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,125 @@
+/* $NetBSD: wii.h,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * Nintendo Wii platform definitions.
+ */
+
+#ifndef _WII_H
+#define _WII_H
+
+#include <powerpc/pio.h>
+
+#define WII_MEM1_BASE			0x00000000
+#define WII_MEM1_SIZE			0x01800000	/* 24 MB */
+#define WII_MEM2_BASE			0x10000000
+#define WII_MEM2_SIZE			0x04000000	/* 64 MB */
+
+#define WII_IOMEM_BASE			0x0c000000
+
+#define	GLOBAL_BASE			0x00000000
+#define GLOBAL_SIZE			0x00003400
+
+#define BROADWAY_BASE			0x0c000000
+#define BROADWAY_SIZE			0x00000004
+
+#define	VI_BASE				0x0c002000
+#define	VI_SIZE				0x00000100
+
+#define PI_BASE				0x0c003000
+#define PI_SIZE				0x00000100
+
+#define HOLLYWOOD_BASE			0x0d000000
+#define HOLLYWOOD_PRIV_BASE		0x0d800000
+#define HOLLYWOOD_SIZE			0x00008000
+
+#define XFB_START			0x01698000
+#define XFB_SIZE			0x00168000
+
+#define DSP_START			0x10000000
+#define DSP_SIZE			0x00004000
+
+#define IPC_START			0x133e0000
+#define IPC_SIZE			0x00020000
+
+#define ARM_START			0x13400000
+#define ARM_SIZE			0x00c00000
+
+#define BUS_FREQ_HZ			243000000
+#define CPU_FREQ_HZ			(BUS_FREQ_HZ * 3)
+#define TIMEBASE_FREQ_HZ		(BUS_FREQ_HZ / 4)
+
+/* Global memory structure */
+#define GLOBAL_MEM1_SIZE		(GLOBAL_BASE + 0x0028)
+#define GLOBAL_CUR_VID_MODE		(GLOBAL_BASE + 0x00cc)
+#define GLOBAL_BUS_SPEED		(GLOBAL_BASE + 0x00f8)
+#define GLOBAL_CPU_SPEED		(GLOBAL_BASE + 0x00fc)
+#define GLOBAL_SYSTEM_TIME		(GLOBAL_BASE + 0x30d8)
+#define GLOBAL_MEM2_SIZE		(GLOBAL_BASE + 0x3118)
+#define GLOBAL_MEM2_AVAIL_START		(GLOBAL_BASE + 0x3124)
+#define GLOBAL_MEM2_AVAIL_END		(GLOBAL_BASE + 0x3128)
+#define GLOBAL_IOS_VERSION		(GLOBAL_BASE + 0x3140)
+
+/* Processor interface registers */
+#define PI_INTSR			(PI_BASE + 0x00)
+#define PI_INTMR			(PI_BASE + 0x04)
+
+/* Processor IRQs */
+#define	PI_IRQ_HOLLYWOOD		14
+
+/* Hollywood registers */
+#define HW_PPCIRQFLAGS			(HOLLYWOOD_BASE + 0x030)
+#define HW_PPCIRQMASK			(HOLLYWOOD_BASE + 0x034)
+#define	HW_ARMIRQFLAGS			(HOLLYWOOD_PRIV_BASE + 0x038)
+#define HW_ARMIRQMASK			(HOLLYWOOD_PRIV_BASE + 0x03c)
+#define HW_AHBPROT			(HOLLYWOOD_PRIV_BASE + 0x064)
+#define HW_GPIOB_OUT			(HOLLYWOOD_BASE + 0x0c0)
+#define HW_GPIO_OUT			(HOLLYWOOD_PRIV_BASE + 0x0e0)
+#define HW_RESETS			(HOLLYWOOD_PRIV_BASE + 0x194)
+#define  RSTB_IOP			__BIT(23)
+#define  RSTBINB			__BIT(0)
+#define HW_VERSION			(HOLLYWOOD_BASE + 0x214)
+#define  HWVER_MASK			__BITS(7,4)
+#define  HWREV_MASK			__BITS(3,0)
+
+/* GPIOs */
+#define GPIO_SLOT_LED			5
+
+/* Blink the slot LED forever at the specified interval. */
+static inline void __dead
+wii_slot_led_blink(u_int interval_us)
+{
+	uint32_t val;
+
+	for (val = in32(HW_GPIOB_OUT); ; val ^= __BIT(GPIO_SLOT_LED)) {
+		delay(interval_us);
+		out32(HW_GPIOB_OUT, val);
+	}
+}
+
+#endif /* !_WII_H */

Index: src/sys/arch/evbppc/wii/autoconf.c
diff -u /dev/null src/sys/arch/evbppc/wii/autoconf.c:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/autoconf.c	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,107 @@
+/*	$NetBSD: autoconf.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $	*/
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)autoconf.c	7.1 (Berkeley) 5/9/91
+ */
+
+/*
+ * Setup the system to run on the current machine.
+ *
+ * Configure() is called at boot time and initializes the vba 
+ * device tables and the memory controller monitoring.  Available
+ * devices are determined (from possibilities mentioned in ioconf.c),
+ * and the drivers are initialized.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/disklabel.h>
+#include <sys/conf.h>
+#include <sys/reboot.h>
+#include <sys/device.h>
+
+#include <powerpc/pte.h>
+
+void findroot(void);
+void disable_intr(void);
+void enable_intr(void);
+
+/*
+ * Determine i/o configuration for a machine.
+ */
+void
+cpu_configure(void)
+{
+
+	if (config_rootfound("mainbus", NULL) == NULL)
+		panic("configure: mainbus not configured");
+
+	genppc_cpu_configure();
+}
+
+void
+cpu_rootconf(void)
+{
+	findroot();
+
+	printf("boot device: %s\n",
+	    booted_device ? device_xname(booted_device) : "<unknown>");
+
+	rootconf();
+}
+
+void
+findroot(void)
+{
+	device_t dev;
+
+	if (booted_device != NULL) {
+		return;
+	}
+
+	if ((dev = device_find_by_driver_unit("ld", 0)) != NULL) {
+		booted_device = dev;
+		booted_partition = 0;
+		return;
+	}
+}
+
+void
+device_register(device_t dev, void *aux)
+{
+	/* do nothing */
+}
Index: src/sys/arch/evbppc/wii/machdep.c
diff -u /dev/null src/sys/arch/evbppc/wii/machdep.c:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/machdep.c	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,424 @@
+/* $NetBSD: machdep.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*
+ * Copyright (c) 2002, 2024 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lenn...@augustsson.net) at Sandburst Corp.
+ *
+ * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+#define _POWERPC_BUS_DMA_PRIVATE
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $");
+
+#include "opt_compat_netbsd.h"
+#include "opt_ddb.h"
+#include "opt_ddbparam.h"
+#include "opt_inet.h"
+#include "opt_ns.h"
+#include "opt_oea.h"
+
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/exec.h>
+#include <sys/extent.h>
+#include <sys/intr.h>
+#include <sys/kernel.h>
+#include <sys/kgdb.h>
+#include <sys/ksyms.h>
+#include <sys/mbuf.h>
+#include <sys/mount.h>
+#include <sys/msgbuf.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+#include <sys/syscallargs.h>
+#include <sys/sysctl.h>
+#include <sys/syslog.h>
+#include <sys/systm.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/powerpc.h>
+#include <machine/wii.h>
+
+#include <powerpc/bus_funcs.h>
+#include <powerpc/db_machdep.h>
+#include <powerpc/pio.h>
+#include <powerpc/pmap.h>
+#include <powerpc/spr.h>
+#include <powerpc/trap.h>
+
+#include <powerpc/oea/bat.h>
+#include <powerpc/oea/spr.h>
+#include <powerpc/pic/picvar.h>
+
+#include <ddb/db_extern.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/rasops/rasops.h>
+#include <dev/wsfont/wsfont.h>
+#include <dev/wscons/wsdisplay_vconsvar.h>
+
+#include <dev/usb/ukbdvar.h>
+
+#include "ksyms.h"
+#include "ukbd.h"
+
+#define IBM750CL_SPR_HID4	1011
+#define	 L2_CCFI		0x00100000	/* L2 complete castout prior
+						 * to L2 flash invalidate.
+						 */
+
+extern u_int l2cr_config;
+
+struct powerpc_bus_space wii_mem_tag = {
+	.pbs_flags = _BUS_SPACE_BIG_ENDIAN |
+		     _BUS_SPACE_MEM_TYPE,
+	.pbs_offset = 0,
+	.pbs_base = 0x0c000000,
+	.pbs_limit = 0x0dffffff,
+	.pbs_extent = NULL,
+};
+
+static char ex_storage[1][EXTENT_FIXED_STORAGE_SIZE(EXTMAP_RANGES)]
+    __attribute__((aligned(8)));
+
+static bus_addr_t
+wii_dma_phys_to_bus_mem(bus_dma_tag_t t, bus_addr_t addr)
+{
+	return addr;
+}
+
+static bus_addr_t
+wii_dma_bus_mem_to_phys(bus_dma_tag_t t, bus_addr_t addr)
+{
+	return addr;
+}
+
+static int
+wii_mem2_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
+    bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
+    int flags)
+{
+	struct mem_region *mem, *avail;
+
+	/* Restrict memory used for DMA to ranges in MEM2 */
+	mem_regions(&mem, &avail);
+	if (mem[1].size == 0) {
+		return ENOMEM;
+	}
+
+	return _bus_dmamem_alloc_range(t, size, alignment, boundary, segs,      
+	    nsegs, rsegs, flags, mem[1].start,
+	    mem[1].start + mem[1].size - PAGE_SIZE - 1);
+}
+
+struct powerpc_bus_dma_tag wii_bus_dma_tag = {
+	0,				/* _bounce_thresh */
+	_bus_dmamap_create,
+	_bus_dmamap_destroy,
+	_bus_dmamap_load,
+	_bus_dmamap_load_mbuf,
+	_bus_dmamap_load_uio,
+	_bus_dmamap_load_raw,
+	_bus_dmamap_unload,
+	_bus_dmamap_sync,
+	_bus_dmamem_alloc,
+	_bus_dmamem_free,
+	_bus_dmamem_map,
+	_bus_dmamem_unmap,
+	_bus_dmamem_mmap,
+	wii_dma_phys_to_bus_mem,
+	wii_dma_bus_mem_to_phys,
+};
+
+struct powerpc_bus_dma_tag wii_mem2_bus_dma_tag = {
+	0,				/* _bounce_thresh */
+	_bus_dmamap_create,
+	_bus_dmamap_destroy,
+	_bus_dmamap_load,
+	_bus_dmamap_load_mbuf,
+	_bus_dmamap_load_uio,
+	_bus_dmamap_load_raw,
+	_bus_dmamap_unload,
+	_bus_dmamap_sync,
+	wii_mem2_dmamem_alloc,
+	_bus_dmamem_free,
+	_bus_dmamem_map,
+	_bus_dmamem_unmap,
+	_bus_dmamem_mmap,
+	wii_dma_phys_to_bus_mem,
+	wii_dma_bus_mem_to_phys,
+};
+
+
+/*
+ * Global variables used here and there
+ */
+struct mem_region physmemr[3], availmemr[3];
+
+void initppc(u_int, u_int, u_int, void *); /* Called from locore */
+void wii_dolphin_elf_loader_id(void);
+
+static void wii_setup(void);
+static void init_decrementer(void);
+
+void
+initppc(u_int startkernel, u_int endkernel, u_int args, void *btinfo)
+{
+	extern u_long ticks_per_sec;
+	extern unsigned char edata[], end[];
+	uint32_t mem2_size;
+	register_t scratch;
+
+	memset(&edata, 0, end - edata); /* clear BSS */
+
+	mem2_size = in32(GLOBAL_MEM2_SIZE);
+
+	/* MEM1 24MB 1T-SRAM */
+	physmemr[0].start = WII_MEM1_BASE;
+	physmemr[0].size = WII_MEM1_SIZE;
+
+	/* MEM2 64MB GDDR3 */
+	physmemr[1].start = WII_MEM2_BASE;
+	physmemr[1].size = mem2_size;
+
+	physmemr[2].size = 0;
+
+	/* MEM1 available memory */
+	availmemr[0].start = ((endkernel & ~0x80000000) + PGOFSET) & ~PGOFSET;
+	availmemr[0].size = physmemr[0].size - availmemr[0].start;
+	/* External framebuffer is at the end of MEM1 */
+	availmemr[0].size -= XFB_SIZE;
+
+	/* MEM2 available memory */
+	availmemr[1].start = physmemr[1].start;
+	availmemr[1].size = physmemr[1].size;
+	if (mem2_size != 0) {
+		/* DSP uses 16KB at the start of MEM2 */
+		availmemr[1].start += DSP_SIZE;
+		availmemr[1].size -= DSP_SIZE;
+		/* IPC and Starlet use memory at the end of MEM2 */
+		availmemr[1].size -= IPC_SIZE;
+		availmemr[1].size -= ARM_SIZE;
+	}
+
+	availmemr[2].size = 0;
+
+#ifdef BOOTHOWTO
+	/*
+	 * boothowto
+	 */
+	boothowto = BOOTHOWTO;
+#endif
+
+	/* HID4[L2_CCFI] must be set to 1 for correct operation of L2 cache */
+	mtspr(IBM750CL_SPR_HID4, mfspr(IBM750CL_SPR_HID4) | L2_CCFI);
+
+	/* Configure L2 cache */
+	l2cr_config = L2CR_L2E | L2CR_L2PE;
+
+	if (bus_space_init(&wii_mem_tag, "iomem",
+			   ex_storage[0], sizeof(ex_storage[0]))) {
+		panic("bus_space_init failed");
+	}
+
+	/*
+	 * Initialize the BAT registers
+	 */
+	oea_batinit(
+	    WII_IOMEM_BASE, BAT_BL_32M,
+	    0);
+
+	/*
+	 * Set up trap vectors
+	 */
+	oea_init(NULL);
+
+	/*
+	 * Get CPU clock
+	 */
+	ticks_per_sec = TIMEBASE_FREQ_HZ;
+	cpu_timebase = ticks_per_sec;
+
+	wii_setup();
+
+	uvm_md_init();
+
+	/*
+	 * Initialize pmap module.
+	 */
+	pmap_bootstrap(startkernel, endkernel);
+
+	/* Now enable translation (and machine checks/recoverable interrupts) */
+	__asm __volatile ("sync; mfmsr %0; ori %0,%0,%1; mtmsr %0; isync"
+			  : "=r"(scratch)
+			  : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI));
+
+	/*
+	 * Setup decrementer
+	 */
+	init_decrementer();
+}
+
+void
+mem_regions(struct mem_region **mem, struct mem_region **avail)
+{
+	*mem = physmemr;
+	*avail = availmemr;
+}
+
+/*
+ * Machine dependent startup code.
+ */
+void
+cpu_startup(void)
+{
+	extern void pi_init_intr(void);
+
+	oea_startup(NULL);
+
+	/*
+	 * Now that we have VM, malloc()s are OK in bus_space.
+	 */
+	bus_space_mallocok();
+
+	/* Set up interrupt controller */
+	pic_init();
+	pi_init_intr();
+	oea_install_extint(pic_ext_intr);
+}
+
+/*
+ * No early console support.
+ */
+void
+consinit(void)
+{
+#if NUKBD > 0
+	ukbd_cnattach();
+#endif
+}
+
+/*
+ * Halt or reboot the machine after syncing/dumping according to howto.
+ */
+void
+cpu_reboot(int howto, char *what)
+{
+	static int syncing;
+	extern void disable_intr(void);
+
+	boothowto = howto;
+	if (!cold && !(howto & RB_NOSYNC) && !syncing) {
+		syncing = 1;
+		vfs_shutdown();		/* sync */
+		resettodr();		/* set wall clock */
+	}
+	splhigh();
+	if (!cold && (howto & RB_DUMP)) {
+		oea_dumpsys();
+	}
+	pmf_system_shutdown(boothowto);
+	doshutdownhooks();
+	/* Force halt on panic to capture the cause on screen. */
+	if (panicstr != NULL) {
+		howto |= RB_HALT;
+	}
+	if (howto & RB_HALT) {
+		printf("halted\n\n");
+		while (1);
+	}
+
+	printf("rebooting\n\n");
+	disable_intr();
+	out32(HW_RESETS, in32(HW_RESETS) & ~RSTBINB);
+	while (1);
+}
+
+static void
+wii_setup(void)
+{
+	/* Turn on the drive slot LED. */
+	out32(HW_GPIOB_OUT, in32(HW_GPIOB_OUT) | __BIT(GPIO_SLOT_LED));
+}
+
+static void
+init_decrementer(void)
+{
+	extern uint32_t ns_per_tick;
+	extern uint32_t ticks_per_intr;
+	extern u_long ticks_per_sec;
+	int scratch, msr;
+
+	KASSERT(ticks_per_sec != 0);
+
+	__asm volatile ("mfmsr %0; andi. %1,%0,%2; mtmsr %1"
+			: "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE));
+	ns_per_tick = 1000000000 / ticks_per_sec;
+	ticks_per_intr = ticks_per_sec / hz;
+	cpu_timebase = ticks_per_sec;
+
+	curcpu()->ci_lasttb = mftbl();
+
+	mtspr(SPR_DEC, ticks_per_intr);
+	mtmsr(msr);
+}
Index: src/sys/arch/evbppc/wii/mainbus.c
diff -u /dev/null src/sys/arch/evbppc/wii/mainbus.c:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/mainbus.c	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,139 @@
+/* $NetBSD: mainbus.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*
+ * Copyright (c) 2002, 2024 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lenn...@augustsson.net) at Sandburst Corp.
+ *
+ * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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: mainbus.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <sys/bus.h>
+#include <machine/wii.h>
+#include <machine/pio.h>
+#include <arch/evbppc/wii/dev/mainbus.h>
+
+#include "locators.h"
+#include "mainbus.h"
+
+extern struct powerpc_bus_space wii_mem_tag;
+extern struct powerpc_bus_dma_tag wii_bus_dma_tag;
+
+int	mainbus_match(device_t, cfdata_t, void *);
+void	mainbus_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(mainbus, 0,
+    mainbus_match, mainbus_attach, NULL, NULL);
+
+int
+mainbus_match(device_t parent, cfdata_t match, void *aux)
+{
+	return 1;
+}
+
+static int
+mainbus_print(void *aux, const char *pnp)
+{
+	struct mainbus_attach_args *mba = aux;
+
+	if (pnp) {
+		aprint_normal("%s at %s", mba->maa_name, pnp);
+	}
+	if (mba->maa_addr != MAINBUSCF_ADDR_DEFAULT) {
+		aprint_normal(" addr 0x%08lx", mba->maa_addr);
+	}
+	if (mba->maa_irq != MAINBUSCF_IRQ_DEFAULT) {
+		aprint_normal(" irq %d", mba->maa_irq);
+	}
+	return UNCONF;
+}
+
+void
+mainbus_attach(device_t parent, device_t self, void *aux)
+{
+	struct mainbus_attach_args maa;
+
+	aprint_normal(": Nintendo Wii\n");
+	aprint_debug_dev(self, "mem1 0x%x, mem2 0x%x\n",
+	    in32(GLOBAL_MEM1_SIZE), in32(GLOBAL_MEM2_SIZE));
+	aprint_debug_dev(self, "cpu %u, bus %u, vidmode %u\n",
+	    in32(GLOBAL_CPU_SPEED), in32(GLOBAL_BUS_SPEED),
+	    in32(GLOBAL_CUR_VID_MODE));
+	aprint_debug_dev(self, "ios version 0x%x\n", in32(GLOBAL_IOS_VERSION));
+
+	maa.maa_bst = &wii_mem_tag;
+	maa.maa_dmat = &wii_bus_dma_tag;
+
+	maa.maa_name = "cpu";
+	maa.maa_addr = MAINBUSCF_ADDR_DEFAULT;
+	maa.maa_irq = MAINBUSCF_IRQ_DEFAULT;
+	config_found(self, &maa, mainbus_print, CFARGS_NONE);
+
+	maa.maa_name = "genfb";
+	maa.maa_addr = VI_BASE;
+	maa.maa_irq = MAINBUSCF_IRQ_DEFAULT;
+	config_found(self, &maa, mainbus_print, CFARGS_NONE);
+
+	maa.maa_name = "hollywood";
+	maa.maa_addr = MAINBUSCF_ADDR_DEFAULT;
+	maa.maa_irq = PI_IRQ_HOLLYWOOD;
+	config_found(self, &maa, mainbus_print, CFARGS_NONE);
+}
+
+static int	cpu_match(device_t, cfdata_t, void *);
+static void	cpu_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(cpu, 0,
+    cpu_match, cpu_attach, NULL, NULL);
+
+extern struct cfdriver cpu_cd;
+
+int
+cpu_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct mainbus_attach_args *maa = aux;
+
+	if (strcmp(maa->maa_name, cpu_cd.cd_name) != 0) {
+		return 0;
+	}
+
+	if (cpu_info[0].ci_dev != NULL) {
+		return 0;
+	}
+
+	return 1;
+}
+
+void
+cpu_attach(device_t parent, device_t self, void *aux)
+{
+	cpu_attach_common(self, 0);
+}
Index: src/sys/arch/evbppc/wii/pic_pi.c
diff -u /dev/null src/sys/arch/evbppc/wii/pic_pi.c:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/pic_pi.c	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,120 @@
+/* $NetBSD: pic_pi.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+/*
+ * Processor interface interrupt controller. Top level controller for all
+ * EXT interrupts.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(0, "$NetBSD: pic_pi.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/bitops.h>
+#include <machine/pio.h>
+#include <machine/intr.h>
+#include <arch/powerpc/pic/picvar.h>
+#include <machine/wii.h>
+
+static uint32_t pic_irqmask;
+static uint32_t pic_actmask;
+
+void pi_init_intr(void);
+
+#define WR4(reg, val)	out32(reg, val)
+#define RD4(reg)	in32(reg)
+
+static void
+pi_enable_irq(struct pic_ops *pic, int irq, int type)
+{
+	pic_irqmask |= __BIT(irq);
+	WR4(PI_INTMR, pic_irqmask & ~pic_actmask);
+}
+
+static void
+pi_disable_irq(struct pic_ops *pic, int irq)
+{
+	pic_irqmask &= ~__BIT(irq);
+	WR4(PI_INTMR, pic_irqmask & ~pic_actmask);
+}
+
+static int
+pi_get_irq(struct pic_ops *pic, int mode)
+{
+	uint32_t raw, pend;
+	int irq;
+
+	raw = RD4(PI_INTSR);
+	pend = raw & pic_irqmask;
+	if (pend == 0) {
+		return 255;
+	}
+	irq = ffs32(pend) - 1;
+
+	pic_actmask |= __BIT(irq);
+	WR4(PI_INTMR, pic_irqmask & ~pic_actmask);
+
+	return irq;
+}
+
+static void
+pi_ack_irq(struct pic_ops *pic, int irq)
+{
+	pic_actmask &= ~__BIT(irq);
+	WR4(PI_INTMR, pic_irqmask & ~pic_actmask);
+	WR4(PI_INTSR, __BIT(irq));
+}
+
+static struct pic_ops pic = {
+	.pic_name = "pi",
+	.pic_numintrs = 32,
+	.pic_cookie = NULL,
+	.pic_enable_irq = pi_enable_irq,
+	.pic_reenable_irq = pi_enable_irq,
+	.pic_disable_irq = pi_disable_irq,
+	.pic_get_irq = pi_get_irq,
+	.pic_ack_irq = pi_ack_irq,
+	.pic_establish_irq = dummy_pic_establish_intr,
+};
+
+void
+pi_init_intr(void)
+{
+	pic_irqmask = 0;
+	pic_actmask = 0;
+
+	/* Mask and clear all interrupts. */
+	WR4(PI_INTMR, 0);
+	WR4(PI_INTSR, ~0U);
+
+	pic_add(&pic);
+}
Index: src/sys/arch/evbppc/wii/wii_locore.S
diff -u /dev/null src/sys/arch/evbppc/wii/wii_locore.S:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/wii_locore.S	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,142 @@
+/*	$NetBSD: wii_locore.S,v 1.1 2024/01/20 21:36:00 jmcneill Exp $	*/
+/*	$OpenBSD: locore.S,v 1.4 1997/01/26 09:06:38 rahnds Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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 "opt_ddb.h"
+#include "opt_kgdb.h"
+#include "opt_multiprocessor.h"
+#include "opt_openpic.h"
+#include "opt_ppcparam.h"
+#include "assym.h"
+
+#include <sys/syscall.h>
+
+#include <machine/param.h>
+#include <machine/psl.h>
+#include <machine/trap.h>
+#include <machine/asm.h>
+
+#include <powerpc/spr.h>
+#include <powerpc/oea/spr.h>
+#include <powerpc/oea/hid.h>
+
+#include "ksyms.h"
+
+/*
+ * Some instructions gas doesn't understand (yet?)
+ */
+#define	bdneq	bdnzf 2,
+
+/*
+ * Globals
+ */
+GLOBAL(startsym)
+	.long	0			/* start symbol table */
+GLOBAL(endsym)
+	.long	0			/* end symbol table */
+/*
+ * This symbol is here for the benefit of kvm_mkdb, and is supposed to
+ * mark the start of kernel text.
+ */
+	.text
+	.globl	_C_LABEL(kernel_text)
+_C_LABEL(kernel_text):
+
+/*
+ * Startup entry.  Note, this must be the first thing in the text
+ * segment!
+ */
+	.text
+	.globl	__start
+__start:
+
+	/* reset MMU to a known state */
+#include "wii_mmuinit.S"
+
+	/* compute end of kernel memory */
+	lis	4,_C_LABEL(end)@ha
+	addi	4,4,_C_LABEL(end)@l
+	rlwinm	4,4,0,1,31
+
+	INIT_CPUINFO(4,1,9,5)
+
+	lis	3,__start@ha
+	addi	3,3,__start@l
+	rlwinm	3,3,0,1,31
+
+	xor	5,5,5
+	xor	6,6,6
+	bl	_C_LABEL(cpu_model_init)
+	bl	_C_LABEL(initppc)
+
+	sync
+	isync
+	mfspr	8,SPR_HID0
+	ori	8, 8, (HID0_ICE | HID0_DCE)@l
+	isync
+	mtspr	SPR_HID0,8
+	sync
+	isync
+
+	bl	_C_LABEL(main)
+
+loop:	b	loop			/* XXX not reached */
+
+	.globl	_C_LABEL(enable_intr)
+_C_LABEL(enable_intr):
+	mfmsr	3
+	ori	3,3,PSL_EE@l
+	mtmsr	3
+	blr
+
+	.globl	_C_LABEL(disable_intr)
+_C_LABEL(disable_intr):
+	mfmsr	3
+	andi.	3,3,~PSL_EE@l
+	mtmsr	3
+	blr
+
+/*
+ * Include common switch / setfault code
+ */
+#include <powerpc/powerpc/locore_subr.S>
+
+/*
+ * Include common trap / exception code
+ */
+#include <powerpc/powerpc/trap_subr.S>
+
+/*
+ * Include PIO routines
+ */
+#include <powerpc/powerpc/pio_subr.S>
Index: src/sys/arch/evbppc/wii/wii_mmuinit.S
diff -u /dev/null src/sys/arch/evbppc/wii/wii_mmuinit.S:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/wii_mmuinit.S	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,132 @@
+/* $NetBSD: wii_mmuinit.S,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (C) 2012 Margarida Gouveia
+ * All rights reserved.
+ *
+ * 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 TOOLS GMBH 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <powerpc/oea/bat.h>
+
+/*
+ * When we are invoked from Wii loaders, the state of the MMU and the BAT
+ * mappings can vary.  In this file we try to reset the MMU to a state
+ * that lets us boot NetBSD.
+ *
+ * This file is being included from wii_locore.S.
+ */
+
+#define	MMU_REALMODE()				\
+	mfmsr	%r12;				\
+	rlwinm	%r12, %r12, 0, ~(PSL_DR|PSL_IR);\
+	sync;					\
+	bl	1f;				\
+1:						\
+	mflr    %r11;				\
+	clrlwi  %r11, %r11, 3;	/* XXX why? */	\
+	addi    %r11, %r11, 2f - 1b;		\
+	mtsrr0  %r11;				\
+	mtsrr1	%r12;	/* Disables the MMU */	\
+	isync;					\
+	rfi;					\
+2:
+
+#define	MMU_VIRTUALMODE()			\
+	bl	3f;				\
+3:						\
+	mflr	%r11;				\
+	addi	%r11, %r11, 4f - 3b;		\
+	mfmsr	%r12;				\
+	ori	%r12, %r12, PSL_DR|PSL_IR;	\
+	mtsrr0	%r11;				\
+	mtsrr1	%r12;	/* Enables the MMU */	\
+	isync;					\
+	rfi;					\
+4:
+
+	MMU_REALMODE()
+
+	/* Reset standard BATs */
+	li	%r11, 0
+	mtibatu 0, %r11
+	mtibatl 0, %r11
+	mtdbatu 0, %r11
+	mtdbatl 0, %r11
+	mtibatu 1, %r11
+	mtibatl 1, %r11
+	mtdbatu 1, %r11
+	mtdbatl 1, %r11
+	mtibatu 2, %r11
+	mtibatl 2, %r11
+	mtdbatu 2, %r11
+	mtdbatl 2, %r11
+	mtibatu 3, %r11
+	mtibatl 3, %r11
+	mtdbatu 3, %r11
+	mtdbatl 3, %r11
+
+	/* Reset high BATs. IBAT[4-7][UL] + DBAT[4-7][UL] */
+	mtspr	560, %r11
+	mtspr	561, %r11
+	mtspr	562, %r11
+	mtspr	563, %r11
+	mtspr	564, %r11
+	mtspr	565, %r11
+	mtspr	566, %r11
+	mtspr	567, %r11
+	mtspr	568, %r11
+	mtspr	569, %r11
+	mtspr	570, %r11
+	mtspr	571, %r11
+	mtspr	572, %r11
+	mtspr	573, %r11
+	mtspr	574, %r11
+	mtspr	575, %r11
+
+	/*
+	 * We need to setup BAT0 as in mmu_oea.c.
+	 */
+	li	%r11, BATU(0x00000000, BAT_BL_256M, BAT_Vs)
+	li	%r12, BATL(0x00000000, BAT_M, BAT_PP_RW)
+	mtdbatu	0, %r11
+	mtdbatl	0, %r12
+	mtibatu	0, %r11
+	mtibatl	0, %r12
+	isync
+
+	/*
+	 * We use BAT1 to be able to write I/O memory, including the
+	 * framebuffer registers.
+	 */
+	/* BATU(0x0c000000, BAT_BL_32M, BAT_Vs) */
+	lis	%r11, 0x0c00
+	ori	%r11, %r11, BAT_BL_32M|BAT_Vs
+	/* BATL(0x0c000000, BAT_I|BAT_G, BAT_PP_RW) */
+	lis	%r12, 0x0c00
+	ori	%r12, %r12, BAT_I|BAT_G|BAT_PP_RW
+	mtdbatu	1, %r11
+	mtdbatl	1, %r12
+	isync
+
+	MMU_VIRTUALMODE()

Index: src/sys/arch/evbppc/wii/dev/ehci_hollywood.c
diff -u /dev/null src/sys/arch/evbppc/wii/dev/ehci_hollywood.c:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/dev/ehci_hollywood.c	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,97 @@
+/* $NetBSD: ehci_hollywood.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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: ehci_hollywood.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+#include <dev/usb/usb_mem.h>
+#include <dev/usb/ehcireg.h>
+#include <dev/usb/ehcivar.h>
+
+#include <machine/wii.h>
+#include "hollywood.h"
+
+extern struct powerpc_bus_dma_tag wii_mem2_bus_dma_tag;
+
+static int	ehci_hollywood_match(device_t, cfdata_t, void *);
+static void	ehci_hollywood_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(ehci_hollywood, sizeof(struct ehci_softc),
+	ehci_hollywood_match, ehci_hollywood_attach, NULL, NULL);
+
+static int
+ehci_hollywood_match(device_t parent, cfdata_t cf, void *aux)
+{
+	return 1;
+}
+
+static void
+ehci_hollywood_attach(device_t parent, device_t self, void *aux)
+{
+	struct hollywood_attach_args *haa = aux;
+	struct ehci_softc *sc = device_private(self);
+	int error;
+
+	sc->sc_dev = self;
+	sc->sc_bus.ub_hcpriv = sc;
+	sc->sc_bus.ub_dmatag = &wii_mem2_bus_dma_tag;
+	sc->sc_bus.ub_revision = USBREV_2_0;
+	sc->sc_flags = EHCIF_32BIT_ACCESS;
+	sc->sc_ncomp = 2;
+	sc->sc_size = 0x100;
+	sc->iot = haa->haa_bst;
+	if (bus_space_map(sc->iot, haa->haa_addr, sc->sc_size, 0, &sc->ioh)) {
+		aprint_error(": couldn't map registers\n");
+		return;
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": EHCI\n");
+
+	sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
+	EOWRITE4(sc, EHCI_USBINTR, 0);
+
+	hollywood_intr_establish(haa->haa_irq, IPL_USB, ehci_intr, sc);
+
+	error = ehci_init(sc);
+	if (error != 0) {
+		aprint_error_dev(self, "init failed, error = %d\n", error);
+		return;
+	}
+
+	sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint,
+	    CFARGS_NONE);
+}
Index: src/sys/arch/evbppc/wii/dev/hollywood.c
diff -u /dev/null src/sys/arch/evbppc/wii/dev/hollywood.c:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/dev/hollywood.c	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,220 @@
+/* $NetBSD: hollywood.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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: hollywood.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/bitops.h>
+
+#include <machine/intr.h>
+#include <machine/wii.h>
+#include <machine/pio.h>
+#include <powerpc/pic/picvar.h>
+
+#include "locators.h"
+#include "mainbus.h"
+#include "hollywood.h"
+
+#define WR4(reg, val)		out32(reg, val)
+#define RD4(reg)		in32(reg)
+
+static struct mainbus_attach_args hollywood_maa;
+static uint32_t pic_irqmask;
+
+static int	hollywood_match(device_t, cfdata_t, void *);
+static void	hollywood_attach(device_t, device_t, void *);
+
+static int	hollywood_search(device_t, cfdata_t, const int *, void *);
+static int	hollywood_print(void *, const char *);
+
+static void	hollywood_intr_init(int);
+static void	hollywood_enable_irq(struct pic_ops *, int, int);
+static void	hollywood_disable_irq(struct pic_ops *, int);
+static int	hollywood_get_irq(struct pic_ops *, int);
+static void	hollywood_ack_irq(struct pic_ops *, int);
+static void	hollywood_establish_irq(struct pic_ops *, int, int, int);
+
+static struct pic_ops hollywood_pic = {
+	.pic_name = "hollywood",
+	.pic_numintrs = 32,
+	.pic_cookie = NULL,
+	.pic_enable_irq = hollywood_enable_irq,
+	.pic_reenable_irq = hollywood_enable_irq,
+	.pic_disable_irq = hollywood_disable_irq,
+	.pic_get_irq = hollywood_get_irq,
+	.pic_ack_irq = hollywood_ack_irq,
+	.pic_establish_irq = hollywood_establish_irq,
+};
+
+CFATTACH_DECL_NEW(hollywood, 0,
+	hollywood_match, hollywood_attach, NULL, NULL);
+
+static int
+hollywood_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct mainbus_attach_args *maa = aux;
+
+	return strcmp(maa->maa_name, "hollywood") == 0;
+}
+
+static void
+hollywood_attach(device_t parent, device_t self, void *aux)
+{
+	uint32_t val;
+
+	hollywood_maa = *(struct mainbus_attach_args *)aux;
+
+	val = RD4(HW_VERSION);
+
+	aprint_naive("\n");
+	aprint_normal(": Hollywood ES%u.%u\n",
+	    (unsigned)__SHIFTOUT(val, HWVER_MASK) + 1,
+	    (unsigned)__SHIFTOUT(val, HWREV_MASK));
+
+	hollywood_intr_init(hollywood_maa.maa_irq);
+
+	config_search(self, NULL,
+	    CFARGS(.search = hollywood_search));
+}
+
+static int
+hollywood_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
+{
+	struct hollywood_attach_args haa;
+
+	haa.haa_bst = hollywood_maa.maa_bst;
+	haa.haa_dmat = hollywood_maa.maa_dmat;
+	if (cf->cf_loc[HOLLYWOODCF_ADDR] != HOLLYWOODCF_ADDR_DEFAULT) {
+		haa.haa_addr = cf->cf_loc[HOLLYWOODCF_ADDR];
+	} else {
+		haa.haa_addr = 0;
+	}
+	haa.haa_irq = cf->cf_loc[HOLLYWOODCF_IRQ];
+
+	if (config_probe(parent, cf, &haa)) {
+		config_attach(parent, cf, &haa, hollywood_print,
+		    CFARGS_NONE);
+	}
+
+	return 0;
+}
+
+static int
+hollywood_print(void *aux, const char *pnp)
+{
+	struct hollywood_attach_args *haa = aux;
+
+	if (pnp != NULL) {
+		return QUIET;
+	}
+
+	if (haa->haa_addr != 0) {
+		aprint_normal(" addr 0x%lx", haa->haa_addr);
+	}
+	if (haa->haa_irq != HOLLYWOODCF_IRQ_DEFAULT) {
+		aprint_normal(" irq %d", haa->haa_irq);
+	}
+
+	return UNCONF;
+}
+
+static void
+hollywood_enable_irq(struct pic_ops *pic, int irq, int type)
+{
+	pic_irqmask |= __BIT(irq);
+	WR4(HW_PPCIRQMASK, pic_irqmask);
+}
+
+static void
+hollywood_disable_irq(struct pic_ops *pic, int irq)
+{
+	pic_irqmask &= ~__BIT(irq);
+	WR4(HW_PPCIRQMASK, pic_irqmask);
+}
+
+static int
+hollywood_get_irq(struct pic_ops *pic, int mode)
+{
+	uint32_t raw, pend;
+	int irq;
+
+	raw = RD4(HW_PPCIRQFLAGS);
+	pend = raw & pic_irqmask;
+	if (pend == 0) {
+		return 255;
+	}
+	irq = ffs32(pend) - 1;
+
+	return irq;
+}
+
+static void
+hollywood_ack_irq(struct pic_ops *pic, int irq)
+{
+	WR4(HW_PPCIRQFLAGS, __BIT(irq));
+}
+
+static void
+hollywood_establish_irq(struct pic_ops *pic, int irq, int type, int pri)
+{
+	uint32_t val;
+
+	/* Mask and clear Starlet interrupt */
+	val = RD4(HW_ARMIRQMASK);
+	val &= ~__BIT(irq);
+	WR4(HW_ARMIRQMASK, val);
+	WR4(HW_ARMIRQFLAGS, __BIT(irq));
+}
+
+static void
+hollywood_intr_init(int irq)
+{
+	pic_irqmask = 0;
+
+	/* Mask and clear all interrupts. */
+	WR4(HW_PPCIRQMASK, 0);
+	WR4(HW_PPCIRQFLAGS, ~0U);
+
+	pic_add(&hollywood_pic);
+
+	intr_establish(irq, IST_LEVEL, IPL_SCHED, pic_handle_intr,
+	    &hollywood_pic);
+}
+
+void *
+hollywood_intr_establish(int irq, int ipl, int (*func)(void *), void *arg)
+{
+	KASSERT(hollywood_pic.pic_intrbase != 0);
+
+	return intr_establish(hollywood_pic.pic_intrbase + irq,
+	    IST_LEVEL, ipl, func, arg);
+}
Index: src/sys/arch/evbppc/wii/dev/hollywood.h
diff -u /dev/null src/sys/arch/evbppc/wii/dev/hollywood.h:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/dev/hollywood.h	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,41 @@
+/* $NetBSD: hollywood.h,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef _WII_DEV_HOLLYWOOD_H_
+#define _WII_DEV_HOLLYWOOD_H_
+
+struct hollywood_attach_args {
+	u_long haa_addr;
+	int haa_irq;
+	bus_space_tag_t haa_bst;
+	bus_dma_tag_t haa_dmat;
+};
+
+void *hollywood_intr_establish(int, int, int (*)(void *), void *);
+
+#endif /* _WII_DEV_HOLLYWOOD_H_ */
Index: src/sys/arch/evbppc/wii/dev/mainbus.h
diff -u /dev/null src/sys/arch/evbppc/wii/dev/mainbus.h:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/dev/mainbus.h	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,40 @@
+/* $NetBSD: mainbus.h,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef _WII_DEV_MAINBUS_H_
+#define _WII_DEV_MAINBUS_H_
+
+struct mainbus_attach_args {
+	const char *maa_name;
+	u_long maa_addr;
+	bus_space_tag_t maa_bst;
+	int maa_irq;
+	bus_dma_tag_t maa_dmat;
+};
+
+#endif /* _WII_DEV_MAINBUS_H_ */
Index: src/sys/arch/evbppc/wii/dev/ohci_hollywood.c
diff -u /dev/null src/sys/arch/evbppc/wii/dev/ohci_hollywood.c:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/dev/ohci_hollywood.c	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,102 @@
+/* $NetBSD: ohci_hollywood.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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: ohci_hollywood.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+#include <dev/usb/usb_mem.h>
+#include <dev/usb/ohcireg.h>
+#include <dev/usb/ohcivar.h>
+
+#include <machine/wii.h>
+#include <machine/pio.h>
+#include "hollywood.h"
+
+#define	USB_CHICKENBITS		0x0d0400cc
+#define	 OHCI_INTR_ENABLE	0x000e1800
+
+extern struct powerpc_bus_dma_tag wii_mem2_bus_dma_tag;
+
+static int	ohci_hollywood_match(device_t, cfdata_t, void *);
+static void	ohci_hollywood_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(ohci_hollywood, sizeof(struct ohci_softc),
+	ohci_hollywood_match, ohci_hollywood_attach, NULL, NULL);
+
+static int
+ohci_hollywood_match(device_t parent, cfdata_t cf, void *aux)
+{
+	return 1;
+}
+
+static void
+ohci_hollywood_attach(device_t parent, device_t self, void *aux)
+{
+	struct hollywood_attach_args *haa = aux;
+	struct ohci_softc *sc = device_private(self);
+	int error;
+
+	sc->sc_dev = self;
+	sc->sc_bus.ub_hcpriv = sc;
+	sc->sc_bus.ub_dmatag = &wii_mem2_bus_dma_tag;
+	sc->sc_flags = 0;
+	sc->sc_size = 0x200;
+	sc->iot = haa->haa_bst;
+	error = bus_space_map(sc->iot, haa->haa_addr, sc->sc_size, 0, &sc->ioh);
+	if (error != 0) {
+		aprint_error(": couldn't map registers (%d)\n", error);
+		return;
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": OHCI\n");
+
+	bus_space_write_4(sc->iot, sc->ioh, OHCI_INTERRUPT_DISABLE,
+	    OHCI_ALL_INTRS);
+
+	out32(USB_CHICKENBITS, in32(USB_CHICKENBITS) | OHCI_INTR_ENABLE);
+
+	hollywood_intr_establish(haa->haa_irq, IPL_USB, ohci_intr, sc);
+
+	error = ohci_init(sc);
+	if (error != 0) {
+		aprint_error_dev(self, "init failed, error = %d\n", error);
+		return;
+	}
+
+	sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint,
+	    CFARGS_NONE);
+}
Index: src/sys/arch/evbppc/wii/dev/resetbtn.c
diff -u /dev/null src/sys/arch/evbppc/wii/dev/resetbtn.c:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/dev/resetbtn.c	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,111 @@
+/* $NetBSD: resetbtn.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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: resetbtn.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/reboot.h>
+#include <powerpc/pio.h>
+#include <dev/sysmon/sysmonvar.h>
+#include <dev/sysmon/sysmon_taskq.h>
+
+#include "hollywood.h"
+
+#define	PI_INTERRUPT_CAUSE	0x0c003000
+#define	 RESET_SWITCH_STATE	__BIT(16)
+
+static int	resetbtn_match(device_t, cfdata_t, void *);
+static void	resetbtn_attach(device_t, device_t, void *);
+
+static int	resetbtn_intr(void *);
+static void	resetbtn_task(void *);
+
+CFATTACH_DECL_NEW(resetbtn, sizeof(struct sysmon_pswitch),
+	resetbtn_match, resetbtn_attach, NULL, NULL);
+
+static int
+resetbtn_match(device_t parent, cfdata_t cf, void *aux)
+{
+	return 1;
+}
+
+static void
+resetbtn_attach(device_t parent, device_t self, void *aux)
+{
+	struct hollywood_attach_args *haa = aux;
+	struct sysmon_pswitch *smpsw = device_private(self);
+	int error;
+
+	KASSERT(device_unit(self) == 0);
+
+	aprint_naive("\n");
+	aprint_normal(": Reset button\n");
+
+	sysmon_task_queue_init();
+
+	smpsw->smpsw_name = device_xname(self);
+	smpsw->smpsw_type = PSWITCH_TYPE_RESET;
+	error = sysmon_pswitch_register(smpsw);
+	if (error != 0) {
+		aprint_error_dev(self,
+		    "unable to register reset button with sysmon: %d\n", error);
+		smpsw = NULL;
+	}
+
+	hollywood_intr_establish(haa->haa_irq, IPL_HIGH, resetbtn_intr, smpsw);
+}
+
+static int
+resetbtn_intr(void *arg)
+{
+	struct sysmon_pswitch *smpsw = arg;
+
+	sysmon_task_queue_sched(0, resetbtn_task, smpsw);
+
+	return 1;
+}
+
+static void
+resetbtn_task(void *arg)
+{
+	struct sysmon_pswitch *smpsw = arg;
+	bool pressed;
+
+	pressed = (in32(PI_INTERRUPT_CAUSE) & RESET_SWITCH_STATE) == 0;
+
+	if (smpsw != NULL) {
+		sysmon_pswitch_event(smpsw,
+		    pressed ? PSWITCH_EVENT_PRESSED : PSWITCH_EVENT_RELEASED);
+	} else if (!pressed) {
+		kern_reboot(0, NULL);
+	}
+}
Index: src/sys/arch/evbppc/wii/dev/sdhc_hollywood.c
diff -u /dev/null src/sys/arch/evbppc/wii/dev/sdhc_hollywood.c:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/dev/sdhc_hollywood.c	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,100 @@
+/* $NetBSD: sdhc_hollywood.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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: sdhc_hollywood.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <dev/sdmmc/sdhcreg.h>
+#include <dev/sdmmc/sdhcvar.h>
+#include <dev/sdmmc/sdmmcvar.h>
+
+#include <machine/wii.h>
+#include "hollywood.h"
+
+#define SDHC_SIZE			0x200
+#define SDHC_HOLLYWOOD_WRITE_DELAY	5
+
+extern struct powerpc_bus_dma_tag wii_mem2_bus_dma_tag;
+
+static int	sdhc_hollywood_match(device_t, cfdata_t, void *);
+static void	sdhc_hollywood_attach(device_t, device_t, void *);
+
+struct sdhc_hollywood_softc {
+	struct sdhc_softc	sc_base;
+	struct sdhc_host	*sc_host[1];
+};
+
+CFATTACH_DECL_NEW(sdhc_hollywood, sizeof(struct sdhc_hollywood_softc),
+	sdhc_hollywood_match, sdhc_hollywood_attach, NULL, NULL);
+
+static int
+sdhc_hollywood_match(device_t parent, cfdata_t cf, void *aux)
+{
+	return 1;
+}
+
+static void
+sdhc_hollywood_attach(device_t parent, device_t self, void *aux)
+{
+	struct hollywood_attach_args *haa = aux;
+	struct sdhc_hollywood_softc *sc = device_private(self);
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+	int error;
+
+	sc->sc_base.sc_dev = self;
+	sc->sc_base.sc_host = sc->sc_host;
+	sc->sc_base.sc_dmat = &wii_mem2_bus_dma_tag;
+	sc->sc_base.sc_flags = SDHC_FLAG_SINGLE_POWER_WRITE |
+			       SDHC_FLAG_32BIT_ACCESS |
+			       SDHC_FLAG_USE_DMA;
+	sc->sc_base.sc_write_delay = SDHC_HOLLYWOOD_WRITE_DELAY;
+
+	bst = haa->haa_bst;
+	if (bus_space_map(bst, haa->haa_addr, SDHC_SIZE, 0, &bsh)) {
+		aprint_error(": couldn't map registers\n");
+		return;
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": SDHC\n");
+
+	hollywood_intr_establish(haa->haa_irq, IPL_SDMMC, sdhc_intr,
+	    &sc->sc_base);
+
+	error = sdhc_host_found(&sc->sc_base, bst, bsh, SDHC_SIZE);
+	if (error != 0) {
+		aprint_error_dev(self,
+		    "couldn't initialize host, error = %d\n", error);
+	}
+}
Index: src/sys/arch/evbppc/wii/dev/vireg.h
diff -u /dev/null src/sys/arch/evbppc/wii/dev/vireg.h:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/dev/vireg.h	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,190 @@
+/* $NetBSD: vireg.h,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef _WII_DEV_VIREG_H
+#define _WII_DEV_VIREG_H
+
+/*
+ * Nintendo Wii Video Interface (VI) registers, from
+ * https://www.gc-forever.com/yagcd/
+ */
+
+/* [2B] VTR - Vertical Timing Register */
+#define VI_VTR		0x00
+#define	 VI_VTR_ACV	__BITS(13,4)
+#define	 VI_VTR_EQU	__BITS(3,0)
+
+/* [2B] DCR - Display Configuration Register */
+#define VI_DCR		0x02
+#define	 VI_DCR_FMT	__BITS(9,8)
+#define   VI_DCR_FMT_NTSC	0
+#define   VI_DCR_FMT_PAL	1
+#define   VI_DCR_FMT_MPAL	2
+#define   VI_DCR_FMT_DEBUG	3
+#define  VI_DCR_LE1	__BITS(7,6)
+#define  VI_DCR_LE0	__BITS(5,4)
+#define	 VI_DCR_DLR	__BIT(3)
+#define  VI_DCR_NIN	__BIT(2)
+#define  VI_DCR_RST	__BIT(1)
+#define  VI_DCR_ENB	__BIT(0)
+
+/* [4B] HTR0 - Horizontal Timing 0 */
+#define VI_HTR0		0x04
+#define	 VI_HTR0_HCS	__BITS(30,24)
+#define	 VI_HTR0_HCE	__BITS(22,16)
+#define	 VI_HTR0_HLW	__BITS(8,0)
+
+/* [4B] HTR1 - Horizontal Timing 1 */
+#define VI_HTR1		0x08
+#define	 VI_HTR1_HBS	__BITS(26,17)
+#define  VI_HTR1_HBE	__BITS(16,7)
+#define	 VI_HTR1_HSY	__BITS(6,0)
+
+/* [4B] VTO - Odd Field Vertical Timing Register */
+#define VI_VTO		0x0c
+#define  VI_VTO_PSB	__BITS(25,16)
+#define  VI_VTO_PRB	__BITS(9,0)
+
+/* [4B] VTE - Even Field Vertical Timing Register */
+#define VI_VTE		0x10
+#define  VI_VTE_PSB	__BITS(25,16)
+#define  VI_VTE_PRB	__BITS(9,0)
+
+/* [4B] BBOI - Odd Field Burst Blanking Interval Register */
+#define VI_BBOI		0x14
+#define  VI_BBOI_BE3	__BITS(31,21)
+#define	 VI_BBOI_BS3	__BITS(20,16)
+#define  VI_BBOI_BE1	__BITS(15,5)
+#define  VI_BBOI_BS1	__BITS(4,0)
+
+/* [4B] BBEI - Even Field Burst Blanking Interval Register */
+#define VI_BBEI		0x18
+#define  VI_BBEI_BE4	__BITS(31,21)
+#define	 VI_BBEI_BS4	__BITS(20,16)
+#define  VI_BBEI_BE2	__BITS(15,5)
+#define  VI_BBEI_BS2	__BITS(4,0)
+
+/* [4B] TFBL - Top Field Base Register (L) */
+#define VI_TFBL		0x1c
+#define  VI_TFBL_PGOFF	__BIT(28)
+#define  VI_TFBL_XOF	__BITS(27,24)
+#define  VI_TFBL_FBB	__BITS(23,0)
+
+/* [4B] TFBR - Top Field Base Register (R) */
+#define VI_TFBR		0x20
+#define	 VI_TFBR_FBB	__BITS(23,0)
+
+/* [4B] BFBL - Bottom Field Base Register (L) */
+#define VI_BFBL		0x24
+#define	 VI_BFBL_PGOFF	__BIT(28)
+#define  VI_BFBL_XOF	__BITS(27,24)
+#define	 VI_BFBL_FBB	__BITS(23,0)
+
+/* [4B] BFBR - Bottom Field Base Register (R) */
+#define VI_BFBR		0x28
+#define	 VI_BFBR_FBB	__BITS(23,0)
+
+/* [2B] DPV - Current Vertical Position */
+#define VI_DPV		0x2c
+#define  VI_DPV_VCT	__BITS(10,0)
+
+/* [2B] DPH - Current Horizontal Position */
+#define VI_DPH		0x2e
+#define	 VI_DPH_HCT	__BITS(10,0)
+
+/* [4B] DI[0-3] - Display Interrupt 0-3 */
+#define VI_DI0		0x30
+#define VI_DI1		0x34
+#define	VI_DI2		0x38
+#define	VI_DI3		0x3c
+#define  VI_DI_INT	__BIT(31)
+#define  VI_DI_ENB	__BIT(28)
+#define	 VI_DI_VCT	__BITS(25,16)
+#define	 VI_DI_HCT	__BITS(9,0)
+
+/* [4B] DL[0-1] - Display Latch Register 0-1 */
+#define VI_DL0		0x40
+#define	VI_DL1		0x44
+#define	 VI_DL_TRG	__BIT(31)
+#define	 VI_DL_VCT	__BITS(26,16)
+#define  VI_DL_HCT	__BITS(10,0)
+
+/* [2B] PICCONF - Picture Configuration Register */
+#define VI_PICCONF	0x48
+#define  VI_PICCONF_READS	__BITS(15,8)
+#define	 VI_PICCONF_STRIDES	__BITS(7,0)
+
+/* [2B] HSR - Horizontal Scaling Register */
+#define VI_HSR		0x4a
+#define	 VI_HSR_HS_EN	__BIT(12)
+#define	 VI_HSR_STP	__BITS(8,0)
+
+/* [4B] FCT[0-6] - Filter Coefficient Table 0-6 */
+#define VI_FCT0		0x50
+#define VI_FCT1		0x54
+#define VI_FCT2		0x58
+#define	VI_FCT3		0x5c
+#define	VI_FCT4		0x60
+#define	VI_FCT5		0x64
+
+/* [4B] ??? */
+#define VI_UNKNOWN_68H	0x68
+
+/* [2B] VICLK - VI Clock Select Register */
+#define	VI_VICLK	0x6c
+#define	 VI_VICLK_SEL	__BIT(0)
+#define	  VI_VICLK_SEL_27MHZ	0
+#define	  VI_VICLK_SEL_54MHZ	1
+
+/* [2B] VISEL - VI DTV Status Register */
+#define VI_VISEL	0x6e
+#define	 VI_VISEL_SEL	__BIT(2)
+
+/* [2B] VI_HSCALINGW - Horizontal Scaling Width */
+#define VI_HSCALINGW	0x70
+#define  VI_HSCALINGW_WIDTH	__BITS(9,0)
+
+/* [2B] HBE - Border HBE */
+#define VI_HBE		0x72
+#define	 VI_HBE_BRDR_EN	__BIT(15)
+#define	 VI_HBE_HBE656	__BITS(9,0)
+
+/* [2B] HBS - Border HBS */
+#define VI_HBS		0x74
+#define  VI_HBS_HBS656	__BITS(9,0)
+
+/* [2B] ??? */
+#define VI_UNKNOWN_76H	0x76
+
+/* [4B] ??? */
+#define VI_UNKNOWN_78H	0x78
+
+/* [4B] ??? */
+#define VI_UNKNOWN_7CH	0x7c
+
+#endif /* !_WII_DEV_VIREG_H */
Index: src/sys/arch/evbppc/wii/dev/wiifb.c
diff -u /dev/null src/sys/arch/evbppc/wii/dev/wiifb.c:1.1
--- /dev/null	Sat Jan 20 21:36:01 2024
+++ src/sys/arch/evbppc/wii/dev/wiifb.c	Sat Jan 20 21:36:00 2024
@@ -0,0 +1,325 @@
+/* $NetBSD: wiifb.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2024 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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: wiifb.c,v 1.1 2024/01/20 21:36:00 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <machine/wii.h>
+
+#include <dev/videomode/videomode.h>
+#include <dev/wsfb/genfbvar.h>
+
+#include "mainbus.h"
+#include "vireg.h"
+
+#define	WIIFB_ERROR_BLINK_INTERVAL	1000000
+
+struct wiifb_mode {
+	const char *		name;
+	u_int			width;
+	u_int			height;
+	u_int			lines;
+};
+
+static uint32_t wiifb_devcmap[16] = {
+	0x00800080,	/* Black */
+	0x1dff1d6b,	/* Blue */
+	0x4b554b4a,	/* Green */
+	0x80808080,	/* Cyan */
+	0x4c544cff,	/* Red */
+	0x3aaa34b5,	/* Magenta */
+	0x7140718a,	/* Brown */
+	0xff80ff80,	/* White */
+	0x80808080,	/* Gray */
+	0xc399c36a,	/* Bright Blue */
+	0xd076d074,	/* Bright Green */
+	0x80808080,	/* Bright Cyan */
+	0x4c544cff,	/* Bright Red */
+	0x3aaa34b5,	/* Bright Magenta */
+	0xe100e194,	/* Bright Yellow */
+	0xff80ff80	/* Bright White */
+};
+
+#define WIIFB_MODE_INDEX(fmt, interlaced)	((fmt << 1) | interlaced)
+	
+static const struct wiifb_mode wiifb_modes[] = {
+	[WIIFB_MODE_INDEX(VI_DCR_FMT_NTSC, 0)] = {
+		.name = "NTSC 480p",
+		.width = 640,
+		.height = 480,
+		.lines = 525,
+	},
+	[WIIFB_MODE_INDEX(VI_DCR_FMT_NTSC, 1)] = {
+		.name = "NTSC 480i",
+		.width = 640,
+		.height = 480,
+		.lines = 525,
+	},
+};
+#define WIIFB_NMODES	__arraycount(wiifb_modes)
+
+struct wiifb_softc {
+	struct genfb_softc	sc_gen;
+
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+
+	void			*sc_bits;
+
+	uint8_t			sc_format;
+	bool			sc_interlaced;
+
+	const struct wiifb_mode	*sc_curmode;
+};
+
+#define	RD2(sc, reg)		\
+	bus_space_read_2((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define	RD4(sc, reg)		\
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define	WR2(sc, reg, val)	\
+	bus_space_write_2((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+#define	WR4(sc, reg, val)	\
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+
+static int	wiifb_match(device_t, cfdata_t, void *);
+static void	wiifb_attach(device_t, device_t, void *);
+
+static void	wiifb_init(struct wiifb_softc *);
+static void	wiifb_set_mode(struct wiifb_softc *, uint8_t, bool);
+static void	wiifb_set_fb(struct wiifb_softc *);
+
+static int	wiifb_ioctl(void *, void *, u_long, void *, int, lwp_t *);
+static paddr_t	wiifb_mmap(void *, void *, off_t, int);
+
+static struct genfb_ops wiifb_ops = {
+	.genfb_ioctl = wiifb_ioctl,
+	.genfb_mmap = wiifb_mmap,
+};
+
+CFATTACH_DECL_NEW(wiifb, sizeof(struct wiifb_softc),
+	wiifb_match, wiifb_attach, NULL, NULL);
+
+static int
+wiifb_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct mainbus_attach_args *maa = aux;
+
+	return strcmp(maa->maa_name, "genfb") == 0;
+}
+
+static void
+wiifb_attach(device_t parent, device_t self, void *aux)
+{
+	struct wiifb_softc *sc = device_private(self);
+	prop_dictionary_t dict = device_properties(self);
+	struct mainbus_attach_args *maa = aux;
+	int error;
+
+	sc->sc_gen.sc_dev = self;
+	sc->sc_bst = maa->maa_bst;
+	error = bus_space_map(sc->sc_bst, maa->maa_addr, VI_SIZE, 0,
+	    &sc->sc_bsh);
+	if (error != 0) {
+		panic("couldn't map registers");
+	}
+	sc->sc_bits = mapiodev(XFB_START, XFB_SIZE, true);
+
+	wiifb_init(sc);
+	wiifb_set_mode(sc, sc->sc_format, sc->sc_interlaced);
+
+	prop_dictionary_set_uint32(dict, "width", sc->sc_curmode->width);
+	prop_dictionary_set_uint32(dict, "height", sc->sc_curmode->height);
+	prop_dictionary_set_uint8(dict, "depth", 16);
+	prop_dictionary_set_uint32(dict, "address", XFB_START);
+	prop_dictionary_set_uint32(dict, "virtual_address",
+	    (uintptr_t)sc->sc_bits);
+	prop_dictionary_set_uint64(dict, "devcmap", (uintptr_t)wiifb_devcmap);
+
+	genfb_init(&sc->sc_gen);
+
+	aprint_naive("\n");
+	aprint_normal(": %s\n", sc->sc_curmode->name);
+
+	genfb_cnattach();
+	prop_dictionary_set_bool(dict, "is_console", true);
+	genfb_attach(&sc->sc_gen, &wiifb_ops);
+}
+
+static void
+wiifb_init(struct wiifb_softc *sc)
+{
+	uint16_t dcr;
+
+#if notyet
+	/* Read current display format and interlaced settings. */
+	dcr = RD2(sc, VI_DCR);
+	sc->sc_format = __SHIFTOUT(dcr, VI_DCR_FMT);
+	sc->sc_interlaced = (dcr & VI_DCR_NIN) == 0;
+
+	/* Reset video interface. */
+	WR2(sc, VI_DCR, dcr | VI_DCR_RST);
+	WR2(sc, VI_DCR, dcr & ~VI_DCR_RST);
+#else
+	/* Force NTSC 480i and reset video interface. */
+	dcr = RD2(sc, VI_DCR);
+	dcr |= VI_DCR_RST;
+	WR2(sc, VI_DCR, dcr);
+	dcr &= ~VI_DCR_RST;
+	dcr &= ~VI_DCR_FMT;
+	dcr |= __SHIFTIN(VI_DCR_FMT_NTSC, VI_DCR_FMT);
+	dcr &= ~VI_DCR_NIN;
+	WR2(sc, VI_DCR, dcr);
+
+	sc->sc_format = VI_DCR_FMT_NTSC;
+	sc->sc_interlaced = 1;
+#endif
+}
+
+static void
+wiifb_set_mode(struct wiifb_softc *sc, uint8_t format, bool interlaced)
+{
+	u_int modeidx;
+	u_int strides, reads;
+
+	modeidx = WIIFB_MODE_INDEX(format, interlaced);
+	if (modeidx >= WIIFB_NMODES || wiifb_modes[modeidx].name == NULL) {
+		panic("Unsupported format (0x%x) / interlaced (%d) settings",
+		    sc->sc_format, sc->sc_interlaced);
+	}
+	sc->sc_curmode = &wiifb_modes[modeidx];
+
+	if (modeidx == WIIFB_MODE_INDEX(VI_DCR_FMT_NTSC, 1)) {
+		/* Magic numbers from YAGCD. */
+		WR2(sc, VI_VTR, 0x0f06);
+		WR4(sc, VI_HTR0, 0x476901AD);
+		WR4(sc, VI_HTR1, 0x02EA5140);
+		WR4(sc, VI_VTO, 0x00030018);
+		WR4(sc, VI_VTE, 0x00020019);
+		WR4(sc, VI_BBOI, 0x410C410C);
+		WR4(sc, VI_BBEI, 0x40ED40ED);
+	} else {
+		/*
+		 * Display mode is not supported. Blink the slot LED to
+		 * indicate failure.
+		 */
+		wii_slot_led_blink(WIIFB_ERROR_BLINK_INTERVAL);
+	}
+
+	/* Picture configuration */
+	strides = (sc->sc_curmode->width * 2) / (interlaced ? 16 : 32);
+	reads = (sc->sc_curmode->width * 2) / 32;
+	WR2(sc, VI_PICCONF,
+	    __SHIFTIN(strides, VI_PICCONF_STRIDES) |
+	    __SHIFTIN(reads, VI_PICCONF_READS));
+
+	WR2(sc, VI_HSR, __SHIFTIN(256, VI_HSR_STP));
+
+	/* Video clock configuration */
+	WR2(sc, VI_VICLK,
+	    interlaced ? VI_VICLK_SEL_27MHZ : VI_VICLK_SEL_54MHZ);
+
+	/* Horizontal scaling width */
+	WR2(sc, VI_HSCALINGW, sc->sc_curmode->width);
+
+	/* Set framebuffer address */
+	wiifb_set_fb(sc);
+}
+
+static void
+wiifb_set_fb(struct wiifb_softc *sc)
+{
+	uint32_t taddr = XFB_START;
+	uint32_t baddr = taddr + (sc->sc_interlaced ?
+				  sc->sc_curmode->width * 2 : 0);
+
+	WR4(sc, VI_TFBL,
+	    VI_TFBL_PGOFF |
+	    __SHIFTIN((taddr >> 5), VI_TFBL_FBB) |
+	    __SHIFTIN((taddr / 2) & 0xf, VI_TFBL_XOF));
+	WR4(sc, VI_TFBR, 0);
+
+	WR4(sc, VI_BFBL,
+	    VI_BFBL_PGOFF |
+	    __SHIFTIN((baddr >> 5), VI_BFBL_FBB) |
+	    __SHIFTIN((baddr / 2) & 0xf, VI_BFBL_XOF));
+	WR4(sc, VI_BFBR, 0);
+}
+
+static int
+wiifb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, lwp_t *l)
+{
+	struct wiifb_softc *sc = v;
+	struct wsdisplayio_bus_id *busid;
+	struct wsdisplayio_fbinfo *fbi;
+
+	switch (cmd) {
+	case WSDISPLAYIO_GTYPE:
+		*(u_int *)data = WSDISPLAY_TYPE_HOLLYWOOD;
+		return 0;
+	case WSDISPLAYIO_GET_BUSID:
+		busid = data;
+		busid->bus_type = WSDISPLAYIO_BUS_SOC;
+		return 0;
+	case WSDISPLAYIO_GET_FBINFO:
+		fbi = data;
+		/*
+		 * rasops info does not match the pixel encoding due to our
+		 * devcmap, so fill out fbinfo manually instead of relying
+		 * on wsdisplayio_get_fbinfo.
+		 */
+		fbi->fbi_fbsize = XFB_SIZE;
+		fbi->fbi_fboffset = 0;
+		fbi->fbi_width = sc->sc_curmode->width;
+		fbi->fbi_height = sc->sc_curmode->height;
+		fbi->fbi_stride = fbi->fbi_width * 2;
+		fbi->fbi_bitsperpixel = 16;
+		fbi->fbi_pixeltype = WSFB_YUY2;
+		fbi->fbi_flags = WSFB_VRAM_IS_RAM;
+		return 0;
+	}
+
+	return EPASSTHROUGH;
+}
+
+static paddr_t
+wiifb_mmap(void *v, void *vs, off_t off, int prot)
+{
+	struct wiifb_softc *sc = v;
+
+	if (off < 0 || off >= XFB_SIZE) {
+		return -1;
+	}
+
+	return bus_space_mmap(sc->sc_bst, XFB_START, off, prot,
+	    BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE);
+}

Reply via email to