Index: head/sys/conf/files.powerpc =================================================================== --- head/sys/conf/files.powerpc (revision 278494) +++ head/sys/conf/files.powerpc (revision 278495) @@ -1,250 +1,244 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # # $FreeBSD$ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # # font.h optional sc \ compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ no-obj no-implicit-rule before-depend \ clean "font.h ${SC_DFLT_FONT}-8x14 ${SC_DFLT_FONT}-8x16 ${SC_DFLT_FONT}-8x8" # # There is only an asm version on ppc64. cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs powerpc compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/atomic/powerpc64/opensolaris_atomic.S optional zfs powerpc64 compile-with "${ZFS_S}" crypto/blowfish/bf_enc.c optional crypto | ipsec crypto/des/des_enc.c optional crypto | ipsec | netsmb dev/bm/if_bm.c optional bm powermac dev/adb/adb_bus.c optional adb dev/adb/adb_kbd.c optional adb dev/adb/adb_mouse.c optional adb dev/adb/adb_hb_if.m optional adb dev/adb/adb_if.m optional adb dev/adb/adb_buttons.c optional adb dev/agp/agp_apple.c optional agp powermac dev/fb/fb.c optional sc dev/fdt/fdt_powerpc.c optional fdt dev/hwpmc/hwpmc_powerpc.c optional hwpmc dev/hwpmc/hwpmc_mpc7xxx.c optional hwpmc dev/hwpmc/hwpmc_ppc970.c optional hwpmc dev/iicbus/ad7417.c optional ad7417 powermac dev/iicbus/adm1030.c optional powermac windtunnel | adm1030 powermac dev/iicbus/adt746x.c optional adt746x powermac dev/iicbus/ds1631.c optional ds1631 powermac dev/iicbus/ds1775.c optional ds1775 powermac dev/iicbus/max6690.c optional max6690 powermac dev/kbd/kbd.c optional sc | vt dev/nand/nfc_fsl.c optional nand mpc85xx # ofw can be either aim or fdt: fdt case handled in files. aim only powerpc specific. dev/ofw/openfirm.c optional aim dev/ofw/openfirmio.c optional aim dev/ofw/ofw_bus_if.m optional aim dev/ofw/ofw_cpu.c optional aim dev/ofw/ofw_if.m optional aim dev/ofw/ofw_bus_subr.c optional aim dev/ofw/ofw_console.c optional aim dev/ofw/ofw_disk.c optional ofwd aim dev/ofw/ofw_iicbus.c optional iicbus aim dev/ofw/ofwbus.c optional aim | fdt dev/ofw/ofw_standard.c optional aim powerpc dev/powermac_nvram/powermac_nvram.c optional powermac_nvram powermac dev/quicc/quicc_bfe_fdt.c optional quicc mpc85xx dev/scc/scc_bfe_macio.c optional scc powermac dev/sec/sec.c optional sec mpc85xx dev/sound/macio/aoa.c optional snd_davbus | snd_ai2s powermac dev/sound/macio/davbus.c optional snd_davbus powermac dev/sound/macio/i2s.c optional snd_ai2s powermac dev/sound/macio/onyx.c optional snd_ai2s iicbus powermac dev/sound/macio/snapper.c optional snd_ai2s iicbus powermac dev/sound/macio/tumbler.c optional snd_ai2s iicbus powermac dev/syscons/scgfbrndr.c optional sc dev/syscons/scterm-teken.c optional sc dev/syscons/scvtb.c optional sc dev/tsec/if_tsec.c optional tsec dev/tsec/if_tsec_fdt.c optional tsec fdt dev/uart/uart_cpu_powerpc.c optional uart dev/usb/controller/ehci_fsl.c optional ehci mpc85xx dev/vt/hw/ofwfb/ofwfb.c optional vt aim kern/kern_clocksource.c standard kern/subr_dummy_vdso_tc.c standard kern/syscalls.c optional ktr kern/subr_sfbuf.c standard libkern/ashldi3.c optional powerpc libkern/ashrdi3.c optional powerpc libkern/bcmp.c standard libkern/cmpdi2.c optional powerpc libkern/divdi3.c optional powerpc libkern/ffs.c standard libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard libkern/lshrdi3.c optional powerpc libkern/memmove.c standard libkern/memset.c standard libkern/moddi3.c optional powerpc libkern/qdivrem.c optional powerpc libkern/ucmpdi2.c optional powerpc libkern/udivdi3.c optional powerpc libkern/umoddi3.c optional powerpc powerpc/aim/interrupt.c optional aim powerpc/aim/locore.S optional aim no-obj powerpc/aim/machdep.c optional aim powerpc/aim/mmu_oea.c optional aim powerpc powerpc/aim/mmu_oea64.c optional aim powerpc/aim/moea64_if.m optional aim powerpc/aim/moea64_native.c optional aim powerpc/aim/mp_cpudep.c optional aim powerpc/aim/slb.c optional aim powerpc64 powerpc/aim/trap.c optional aim powerpc/aim/uma_machdep.c optional aim powerpc/booke/interrupt.c optional booke powerpc/booke/locore.S optional booke no-obj powerpc/booke/machdep.c optional booke powerpc/booke/machdep_e500.c optional booke_e500 powerpc/booke/mp_cpudep.c optional booke smp powerpc/booke/platform_bare.c optional booke powerpc/booke/pmap.c optional booke powerpc/booke/trap.c optional booke powerpc/cpufreq/dfs.c optional cpufreq powerpc/cpufreq/pcr.c optional cpufreq aim powerpc/cpufreq/pmufreq.c optional cpufreq aim pmu powerpc/fpu/fpu_add.c optional fpu_emu powerpc/fpu/fpu_compare.c optional fpu_emu powerpc/fpu/fpu_div.c optional fpu_emu powerpc/fpu/fpu_emu.c optional fpu_emu powerpc/fpu/fpu_explode.c optional fpu_emu powerpc/fpu/fpu_implode.c optional fpu_emu powerpc/fpu/fpu_mul.c optional fpu_emu powerpc/fpu/fpu_sqrt.c optional fpu_emu powerpc/fpu/fpu_subr.c optional fpu_emu powerpc/mambo/mambocall.S optional mambo powerpc/mambo/mambo.c optional mambo powerpc/mambo/mambo_console.c optional mambo powerpc/mambo/mambo_disk.c optional mambo powerpc/mpc85xx/atpic.c optional mpc85xx isa powerpc/mpc85xx/ds1553_bus_fdt.c optional ds1553 fdt powerpc/mpc85xx/ds1553_core.c optional ds1553 powerpc/mpc85xx/i2c.c optional iicbus fdt powerpc/mpc85xx/isa.c optional mpc85xx isa powerpc/mpc85xx/lbc.c optional mpc85xx powerpc/mpc85xx/mpc85xx.c optional mpc85xx powerpc/mpc85xx/platform_mpc85xx.c optional mpc85xx powerpc/mpc85xx/pci_mpc85xx.c optional pci mpc85xx powerpc/ofw/ofw_machdep.c standard powerpc/ofw/ofw_pci.c optional pci powerpc/ofw/ofw_pcibus.c optional pci powerpc/ofw/ofw_pcib_pci.c optional pci powerpc/ofw/ofw_real.c optional aim powerpc/ofw/ofw_syscons.c optional sc aim powerpc/ofw/ofwcall32.S optional aim powerpc powerpc/ofw/ofwcall64.S optional aim powerpc64 powerpc/ofw/ofwmagic.S optional aim powerpc/ofw/openpic_ofw.c optional aim | fdt powerpc/ofw/rtas.c optional aim powerpc/powermac/ata_kauai.c optional powermac ata | powermac atamacio powerpc/powermac/ata_macio.c optional powermac ata | powermac atamacio powerpc/powermac/ata_dbdma.c optional powermac ata | powermac atamacio powerpc/powermac/atibl.c optional powermac atibl powerpc/powermac/cuda.c optional powermac cuda powerpc/powermac/cpcht.c optional powermac pci powerpc/powermac/dbdma.c optional powermac pci powerpc/powermac/fcu.c optional powermac fcu powerpc/powermac/grackle.c optional powermac pci powerpc/powermac/hrowpic.c optional powermac pci powerpc/powermac/kiic.c optional powermac kiic powerpc/powermac/macgpio.c optional powermac pci powerpc/powermac/macio.c optional powermac pci powerpc/powermac/nvbl.c optional powermac nvbl powerpc/powermac/platform_powermac.c optional powermac powerpc/powermac/powermac_thermal.c optional powermac powerpc/powermac/pswitch.c optional powermac pswitch powerpc/powermac/pmu.c optional powermac pmu powerpc/powermac/smu.c optional powermac smu powerpc/powermac/smusat.c optional powermac smu powerpc/powermac/uninorth.c optional powermac powerpc/powermac/uninorthpci.c optional powermac pci powerpc/powermac/vcoregpio.c optional powermac powerpc/powerpc/altivec.c standard powerpc/powerpc/autoconf.c standard powerpc/powerpc/bcopy.c standard powerpc/powerpc/bus_machdep.c standard powerpc/powerpc/busdma_machdep.c standard powerpc/powerpc/clock.c standard powerpc/powerpc/copyinout.c standard powerpc/powerpc/copystr.c standard powerpc/powerpc/cpu.c standard powerpc/powerpc/db_disasm.c optional ddb powerpc/powerpc/db_hwwatch.c optional ddb powerpc/powerpc/db_interface.c optional ddb powerpc/powerpc/db_trace.c optional ddb powerpc/powerpc/dump_machdep.c standard powerpc/powerpc/elf32_machdep.c optional powerpc | compat_freebsd32 powerpc/powerpc/elf64_machdep.c optional powerpc64 powerpc/powerpc/exec_machdep.c standard powerpc/powerpc/fpu.c standard powerpc/powerpc/fuswintr.c standard powerpc/powerpc/gdb_machdep.c optional gdb powerpc/powerpc/in_cksum.c optional inet | inet6 powerpc/powerpc/intr_machdep.c standard powerpc/powerpc/iommu_if.m standard powerpc/powerpc/mem.c optional mem powerpc/powerpc/mmu_if.m standard powerpc/powerpc/mp_machdep.c optional smp powerpc/powerpc/nexus.c standard powerpc/powerpc/openpic.c standard powerpc/powerpc/pic_if.m standard powerpc/powerpc/pmap_dispatch.c standard powerpc/powerpc/platform.c standard powerpc/powerpc/platform_if.m standard powerpc/powerpc/ptrace_machdep.c standard powerpc/powerpc/sc_machdep.c optional sc powerpc/powerpc/setjmp.S standard powerpc/powerpc/sigcode32.S optional powerpc | compat_freebsd32 powerpc/powerpc/sigcode64.S optional powerpc64 powerpc/powerpc/swtch32.S optional powerpc powerpc/powerpc/swtch64.S optional powerpc64 powerpc/powerpc/stack_machdep.c optional ddb | stack powerpc/powerpc/suswintr.c standard powerpc/powerpc/syncicache.c standard powerpc/powerpc/sys_machdep.c standard powerpc/powerpc/uio_machdep.c standard powerpc/powerpc/vm_machdep.c standard powerpc/ps3/ehci_ps3.c optional ps3 ehci powerpc/ps3/ohci_ps3.c optional ps3 ohci powerpc/ps3/if_glc.c optional ps3 glc powerpc/ps3/mmu_ps3.c optional ps3 powerpc/ps3/platform_ps3.c optional ps3 powerpc/ps3/ps3bus.c optional ps3 powerpc/ps3/ps3cdrom.c optional ps3 scbus powerpc/ps3/ps3disk.c optional ps3 powerpc/ps3/ps3pic.c optional ps3 powerpc/ps3/ps3_syscons.c optional ps3 vt powerpc/ps3/ps3-hvcall.S optional ps3 powerpc/pseries/phyp-hvcall.S optional pseries powerpc64 powerpc/pseries/mmu_phyp.c optional pseries powerpc64 powerpc/pseries/phyp_console.c optional pseries powerpc64 uart powerpc/pseries/phyp_llan.c optional llan powerpc/pseries/phyp_vscsi.c optional pseries powerpc64 scbus powerpc/pseries/platform_chrp.c optional pseries powerpc/pseries/plpar_iommu.c optional pseries powerpc64 powerpc/pseries/plpar_pcibus.c optional pseries powerpc64 pci powerpc/pseries/rtas_dev.c optional pseries powerpc/pseries/rtas_pci.c optional pseries pci powerpc/pseries/vdevice.c optional pseries powerpc64 powerpc/pseries/xics.c optional pseries powerpc64 powerpc/psim/iobus.c optional psim powerpc/psim/ata_iobus.c optional ata psim powerpc/psim/openpic_iobus.c optional psim powerpc/psim/uart_iobus.c optional uart psim -powerpc/wii/platform_wii.c optional wii -powerpc/wii/wii_bus.c optional wii -powerpc/wii/wii_pic.c optional wii -powerpc/wii/wii_fb.c optional wii -powerpc/wii/wii_gpio.c optional wii wiigpio -powerpc/wii/wii_ipc.c optional wii Index: head/sys/conf/options.powerpc =================================================================== --- head/sys/conf/options.powerpc (revision 278494) +++ head/sys/conf/options.powerpc (revision 278495) @@ -1,35 +1,34 @@ # $FreeBSD$ # Options specific to the powerpc platform kernels AIM opt_global.h BOOKE opt_global.h BOOKE_E500 opt_global.h BOOKE_PPC4XX opt_global.h CELL POWERPC POWERPC64 FPU_EMU COMPAT_FREEBSD32 opt_compat.h GFB_DEBUG opt_gfb.h GFB_NO_FONT_LOADING opt_gfb.h GFB_NO_MODE_CHANGE opt_gfb.h MPC85XX opt_platform.h POWERMAC opt_platform.h PS3 opt_platform.h MAMBO PSERIES PSIM -WII opt_platform.h SC_OFWFB opt_ofwfb.h OFWCONS_POLL_HZ opt_ofw.h # AGP debugging support AGP_DEBUG opt_agp.h Index: head/sys/powerpc/wii/wii_exireg.h =================================================================== --- head/sys/powerpc/wii/wii_exireg.h (revision 278494) +++ head/sys/powerpc/wii/wii_exireg.h (nonexistent) @@ -1,35 +0,0 @@ -/*- - * 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 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. - * - * $FreeBSD$ - */ - -#ifndef _POWERPC_WII_WII_EXIREG_H -#define _POWERPC_WII_WII_EXIREG_H - -#define WIIEXI_REG_ADDR 0x0d006800 -#define WIIEXI_REG_LEN 0x40 - -#endif /* _POWERPC_WII_WII_IPCREG_H */ Property changes on: head/sys/powerpc/wii/wii_exireg.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/wii_ipcreg.h =================================================================== --- head/sys/powerpc/wii/wii_ipcreg.h (revision 278494) +++ head/sys/powerpc/wii/wii_ipcreg.h (nonexistent) @@ -1,102 +0,0 @@ -/*- - * 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 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. - * - * $FreeBSD$ - */ - -#ifndef _POWERPC_WII_WII_IPCREG_H -#define _POWERPC_WII_WII_IPCREG_H - -#define WIIIPC_REG_ADDR 0x0d000000 -#define WIIIPC_REG_LEN 0x40 -#define WIIIPC_IOH_ADDR 0x133e0000 -#define WIIIPC_IOH_LEN 0xc20000 - -#define WIIIPC_TXBUF 0x00 -#define WIIIPC_CSR 0x04 -#define WIIIPC_CSR_TXSTART 0x01 -#define WIIIPC_CSR_TBEI 0x02 -#define WIIIPC_CSR_RBFI 0x04 -#define WIIIPC_CSR_RXREADY 0x08 -#define WIIIPC_CSR_RBFIMASK 0x10 -#define WIIIPC_CSR_TBEIMASK 0x20 -#define WIIIPC_RXBUF 0x08 -#define WIIIPC_ISR 0x30 -#define WIIIPC_ISR_MAGIC 0x40000000 - -enum wiiipc_cmd { - WIIIPC_CMD_OPEN = 1, - WIIIPC_CMD_CLOSE = 2, - WIIIPC_CMD_READ = 3, - WIIIPC_CMD_WRITE = 4, - WIIIPC_CMD_SEEK = 5, - WIIIPC_CMD_IOCTL = 6, - WIIIPC_CMD_IOCTLV = 7, - WIIIPC_CMD_ASYNCRESP = 8 -}; - -struct wiiipc_ipc_msg { - uint32_t ipc_cmd; - int32_t ipc_result; - int32_t ipc_fd; /* WIIIPC_CMD_ASYNCRESP - the original cmd */ - union { - struct { - intptr_t pathname; - uint32_t mode; - } _ipc_open; - struct { - intptr_t data; - uint32_t len; - } _ipc_read, _ipc_write; - struct { - int32_t offset; - int32_t whence; - } _ipc_seek; - struct { - uint32_t request; - intptr_t ibuf; - uint32_t ilen; - intptr_t obuf; - uint32_t olen; - } _ipc_ioctl; - struct { - uint32_t request; - uint32_t argin; - uint32_t argout; - intptr_t iovec; - } _ipc_ioctlv; - uint32_t _ipc_argv[5]; - } args; -} __attribute__((packed)); - -CTASSERT(sizeof(struct wiiipc_ipc_msg) == 32); - -#define ipc_open args._ipc_open -#define ipc_read args._ipc_read -#define ipc_write args._ipc_write -#define ipc_ioctl args._ipc_ioctl -#define ipc_ioctlv args._ipc_ioctlv - -#endif /* _POWERPC_WII_WII_IPCREG_H */ Property changes on: head/sys/powerpc/wii/wii_ipcreg.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/ios_if.m =================================================================== --- head/sys/powerpc/wii/ios_if.m (revision 278494) +++ head/sys/powerpc/wii/ios_if.m (nonexistent) @@ -1,64 +0,0 @@ -#- -# Copyright (c) 2013 Rui Paulo -# 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 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 AUTHOR 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. -# -# $FreeBSD$ -# - -#include -#include - -INTERFACE ios; - -METHOD int open { - device_t dev; - const char *path; - int mode; -}; - -METHOD int close { - device_t dev; - int fd; -}; - -METHOD int ioctl { - device_t dev; - int fd; - unsigned int request; - void *ibuf; - size_t ilen; - void *obuf; - size_t olen; -}; - -METHOD int ioctlv { - device_t dev; - int fd; - unsigned int request; - struct iovec *in; - size_t ilen; - struct iovec *out; - size_t olen; -}; - Property changes on: head/sys/powerpc/wii/ios_if.m ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/platform_wii.c =================================================================== --- head/sys/powerpc/wii/platform_wii.c (revision 278494) +++ head/sys/powerpc/wii/platform_wii.c (nonexistent) @@ -1,161 +0,0 @@ -/*- - * 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, - * without modification, immediately at the beginning of the file. - * 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "platform_if.h" - -static int wii_probe(platform_t); -static int wii_attach(platform_t); -static void wii_mem_regions(platform_t, struct mem_region *, - int *, struct mem_region *, int *); -static unsigned long wii_timebase_freq(platform_t, struct cpuref *); -static void wii_reset(platform_t); -static void wii_cpu_idle(sbintime_t); - -extern void wiibus_reset_system(void); - -static platform_method_t wii_methods[] = { - PLATFORMMETHOD(platform_probe, wii_probe), - PLATFORMMETHOD(platform_attach, wii_attach), - PLATFORMMETHOD(platform_mem_regions, wii_mem_regions), - PLATFORMMETHOD(platform_timebase_freq, wii_timebase_freq), - PLATFORMMETHOD(platform_reset, wii_reset), - - PLATFORMMETHOD_END -}; - -static platform_def_t wii_platform = { - "wii", - wii_methods, - 0 -}; - -PLATFORM_DEF(wii_platform); - -static int -wii_probe(platform_t plat) -{ - register_t vers = mfpvr(); - - /* - * The Wii includes a PowerPC 750CL with custom modifications - * ("Broadway"). - * For now, we just assume that if we are running on a - * PowerPC 750CL, then this platform is a Nintendo Wii. - */ - if ((vers & 0xfffff0e0) == (MPC750 << 16 | MPC750CL)) - return (BUS_PROBE_SPECIFIC); - - return (ENXIO); -} - -static int -wii_attach(platform_t plat) -{ - cpu_idle_hook = wii_cpu_idle; - - return (0); -} - -static void -wii_mem_regions(platform_t plat, struct mem_region *phys, int *physsz, - struct mem_region *avail_regions, int *availsz) -{ - /* 24MB 1T-SRAM */ - avail_regions[0].mr_start = 0x00000000; - avail_regions[0].mr_size = 0x01800000; - - /* - * Reserve space for the framebuffer which is located - * at the end of this 24MB memory region. See wii_fbreg.h. - */ - avail_regions[0].mr_size -= WIIFB_FB_LEN; - - /* 64MB GDDR3 SDRAM */ - avail_regions[1].mr_start = 0x10000000; - avail_regions[1].mr_size = 0x04000000; - - /* - * Reserve space for the DSP. - */ - avail_regions[1].mr_start += 0x4000; - avail_regions[1].mr_size -= 0x4000; - - /* - * Reserve space for the IOS I/O memory. - */ - avail_regions[1].mr_size -= WIIIPC_IOH_LEN + 1; - - memcpy(phys, avail_regions, 2*sizeof(*avail_regions)); - *physsz = *availsz = 2; -} - -static u_long -wii_timebase_freq(platform_t plat, struct cpuref *cpuref) -{ - - /* Bus Frequency (243MHz) / 4 */ - return (60750000); -} - -static void -wii_reset(platform_t plat __unused) -{ - - wiibus_reset_system(); -} - -static void -wii_cpu_idle(sbintime_t sbt) -{ -} Property changes on: head/sys/powerpc/wii/platform_wii.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/wii_gpioreg.h =================================================================== --- head/sys/powerpc/wii/wii_gpioreg.h (revision 278494) +++ head/sys/powerpc/wii/wii_gpioreg.h (nonexistent) @@ -1,38 +0,0 @@ -/*- - * 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 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. - * - * $FreeBSD$ - */ - -#ifndef _POWERPC_WII_WII_GPIOREG_H -#define _POWERPC_WII_WII_GPIOREG_H - -#define WIIGPIO_NPINS 64 -#define WIIGPIO_POWEROFF_PIN 33 - -#define WIIGPIO_REG_ADDR 0x0d8000c0 -#define WIIGPIO_REG_LEN 0x40 - -#endif /* _POWERPC_WII_WII_GPIOREG_H */ Property changes on: head/sys/powerpc/wii/wii_gpioreg.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/wii_fbvar.h =================================================================== --- head/sys/powerpc/wii/wii_fbvar.h (revision 278494) +++ head/sys/powerpc/wii/wii_fbvar.h (nonexistent) @@ -1,857 +0,0 @@ -/*- - * 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, - * without modification, immediately at the beginning of the file. - * 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. - * - * $FreeBSD$ - */ - -#ifndef _POWERPC_WII_WIIFB_H -#define _POWERPC_WII_WIIFB_H - -#define WIIFB_FONT_HEIGHT 8 - -enum wiifb_format { - WIIFB_FORMAT_NTSC = 0, - WIIFB_FORMAT_PAL = 1, - WIIFB_FORMAT_MPAL = 2, - WIIFB_FORMAT_DEBUG = 3 -}; - -enum wiifb_mode { - WIIFB_MODE_NTSC_480i = 0, - WIIFB_MODE_NTSC_480p = 1, - WIIFB_MODE_PAL_576i = 2, - WIIFB_MODE_PAL_480i = 3, - WIIFB_MODE_PAL_480p = 4 -}; - -struct wiifb_mode_desc { - const char *fd_name; - unsigned int fd_width; - unsigned int fd_height; - unsigned int fd_lines; - uint8_t fd_flags; -#define WIIFB_MODE_FLAG_PROGRESSIVE 0x00 -#define WIIFB_MODE_FLAG_INTERLACED 0x01 -}; - -struct wiifb_softc { - video_adapter_t sc_va; - struct cdev *sc_si; - int sc_console; - - intptr_t sc_reg_addr; - unsigned int sc_reg_size; - - intptr_t sc_fb_addr; - unsigned int sc_fb_size; - - unsigned int sc_height; - unsigned int sc_width; - unsigned int sc_stride; - - unsigned int sc_xmargin; - unsigned int sc_ymargin; - - boolean_t sc_component; - enum wiifb_format sc_format; - struct wiifb_mode_desc *sc_mode; - - unsigned int sc_vtiming; - unsigned int sc_htiming; - - unsigned char *sc_font; - int sc_initialized; - int sc_rrid; -}; - -/* - * Vertical timing - * 16 bit - */ -#define WIIFB_REG_VTIMING 0x00 -struct wiifb_vtiming { - uint8_t vt_eqpulse; - uint16_t vt_actvideo; -}; - -static __inline void -wiifb_vtiming_read(struct wiifb_softc *sc, struct wiifb_vtiming *vt) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMING); - - vt->vt_eqpulse = *reg & 0xf; - vt->vt_actvideo = (*reg >> 4) & 0x3ff; -} - -static __inline void -wiifb_vtiming_write(struct wiifb_softc *sc, struct wiifb_vtiming *vt) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMING); - - *reg = ((vt->vt_actvideo & 0x3ff) << 4) | - (vt->vt_eqpulse & 0xf); - powerpc_sync(); -} - -/* - * Display configuration - * 16 bit - */ -#define WIIFB_REG_DISPCFG 0x02 -struct wiifb_dispcfg { - uint8_t dc_enable; - uint8_t dc_reset; - uint8_t dc_noninterlaced; - uint8_t dc_3dmode; - uint8_t dc_latchenb0; - uint8_t dc_latchenb1; - enum wiifb_format dc_format; -}; - -static __inline void -wiifb_dispcfg_read(struct wiifb_softc *sc, struct wiifb_dispcfg *dc) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_DISPCFG); - - dc->dc_enable = *reg & 0x1; - dc->dc_reset = (*reg >> 1) & 0x1; - dc->dc_noninterlaced = (*reg >> 2) & 0x1; - dc->dc_3dmode = (*reg >> 3) & 0x1; - dc->dc_latchenb0 = (*reg >> 4) & 0x3; - dc->dc_latchenb1 = (*reg >> 6) & 0x3; - dc->dc_format = (*reg >> 8) & 0x3; -} - -static __inline void -wiifb_dispcfg_write(struct wiifb_softc *sc, struct wiifb_dispcfg *dc) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_DISPCFG); - - *reg = ((dc->dc_format & 0x3) << 8) | - ((dc->dc_latchenb1 & 0x3) << 6) | - ((dc->dc_latchenb0 & 0x3) << 4) | - ((dc->dc_3dmode & 0x1) << 3) | - ((dc->dc_noninterlaced & 0x1) << 2) | - ((dc->dc_reset & 0x1) << 1) | - (dc->dc_enable & 0x1); - powerpc_sync(); -} - -/* - * Horizontal Timing 0 - * 32 bit - */ -#define WIIFB_REG_HTIMING0 0x04 -struct wiifb_htiming0 { - uint16_t ht0_hlinew; /* half line width */ - uint8_t ht0_hcolourend; - uint8_t ht0_hcolourstart; -}; - -static __inline void -wiifb_htiming0_read(struct wiifb_softc *sc, struct wiifb_htiming0 *ht0) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING0); - - ht0->ht0_hlinew = *reg & 0x1ff; - ht0->ht0_hcolourend = (*reg >> 16) & 0x7f; - ht0->ht0_hcolourstart = (*reg >> 24) & 0x7f; -} - -static __inline void -wiifb_htiming0_write(struct wiifb_softc *sc, struct wiifb_htiming0 *ht0) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING0); - - *reg = ((ht0->ht0_hcolourstart & 0x7f) << 24) | - ((ht0->ht0_hcolourend & 0x7f) << 16) | - (ht0->ht0_hlinew & 0x1ff); - powerpc_sync(); -} -/* - * Horizontal Timing 1 - * 32 bit - */ -#define WIIFB_REG_HTIMING1 0x08 -struct wiifb_htiming1 { - uint8_t ht1_hsyncw; - uint16_t ht1_hblankend; - uint16_t ht1_hblankstart; -}; - -static __inline void -wiifb_htiming1_read(struct wiifb_softc *sc, struct wiifb_htiming1 *ht1) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING1); - - ht1->ht1_hsyncw = *reg & 0x7f; - ht1->ht1_hblankend = (*reg >> 7) & 0x3ff; - ht1->ht1_hblankstart = (*reg >> 17) & 0x3ff; -} - -static __inline void -wiifb_htiming1_write(struct wiifb_softc *sc, struct wiifb_htiming1 *ht1) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING1); - - *reg = ((ht1->ht1_hblankstart & 0x3ff) << 17) | - ((ht1->ht1_hblankend & 0x3ff) << 7) | - (ht1->ht1_hsyncw & 0x7f); - powerpc_sync(); -} - -/* - * Vertical Timing Odd - * 32 bit - */ -#define WIIFB_REG_VTIMINGODD 0x0c -struct wiifb_vtimingodd { - uint16_t vto_preb; /* pre blanking */ - uint16_t vto_postb; /* post blanking */ -}; - -static __inline void -wiifb_vtimingodd_read(struct wiifb_softc *sc, struct wiifb_vtimingodd *vto) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGODD); - - vto->vto_preb = *reg & 0x3ff; - vto->vto_postb = (*reg >> 16) & 0x3ff; -} - -static __inline void -wiifb_vtimingodd_write(struct wiifb_softc *sc, struct wiifb_vtimingodd *vto) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGODD); - - *reg = ((vto->vto_postb & 0x3ff) << 16) | - (vto->vto_preb & 0x3ff); - powerpc_sync(); -} - -/* - * Vertical Timing Even - * 32 bit - */ -#define WIIFB_REG_VTIMINGEVEN 0x10 -struct wiifb_vtimingeven { - uint16_t vte_preb; /* pre blanking */ - uint16_t vte_postb; /* post blanking */ -}; - -static __inline void -wiifb_vtimingeven_read(struct wiifb_softc *sc, struct wiifb_vtimingeven *vte) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGEVEN); - - vte->vte_preb = *reg & 0x3ff; - vte->vte_postb = (*reg >> 16) & 0x3ff; -} - -static __inline void -wiifb_vtimingeven_write(struct wiifb_softc *sc, struct wiifb_vtimingeven *vte) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGEVEN); - - *reg = ((vte->vte_postb & 0x3ff) << 16) | - (vte->vte_preb & 0x3ff); - powerpc_sync(); -} - -/* - * Burst Blanking Odd Interval - * 32 bit - */ -#define WIIFB_REG_BURSTBLANKODD 0x14 -struct wiifb_burstblankodd { - uint8_t bbo_bs1; - uint16_t bbo_be1; - uint8_t bbo_bs3; - uint16_t bbo_be3; -}; - -static __inline void -wiifb_burstblankodd_read(struct wiifb_softc *sc, - struct wiifb_burstblankodd *bbo) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKODD); - - bbo->bbo_bs1 = *reg & 0x1f; - bbo->bbo_be1 = (*reg >> 5) & 0x7ff; - bbo->bbo_bs3 = (*reg >> 16) & 0x1f; - bbo->bbo_be3 = (*reg >> 21) & 0x7ff; -} - -static __inline void -wiifb_burstblankodd_write(struct wiifb_softc *sc, - struct wiifb_burstblankodd *bbo) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKODD); - - *reg = ((bbo->bbo_be3 & 0x7ff) << 21) | - ((bbo->bbo_bs3 & 0x1f) << 16) | - ((bbo->bbo_be1 & 0x7ff) << 5) | - (bbo->bbo_bs1 & 0x1f); - powerpc_sync(); -} - -/* - * Burst Blanking Even Interval - * 32 bit - */ -#define WIIFB_REG_BURSTBLANKEVEN 0x18 -struct wiifb_burstblankeven { - uint8_t bbe_bs2; - uint16_t bbe_be2; - uint8_t bbe_bs4; - uint16_t bbe_be4; -}; - -static __inline void -wiifb_burstblankeven_read(struct wiifb_softc *sc, - struct wiifb_burstblankeven *bbe) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKEVEN); - - bbe->bbe_bs2 = *reg & 0x1f; - bbe->bbe_be2 = (*reg >> 5) & 0x7ff; - bbe->bbe_bs4 = (*reg >> 16) & 0x1f; - bbe->bbe_be4 = (*reg >> 21) & 0x7ff; -} - -static __inline void -wiifb_burstblankeven_write(struct wiifb_softc *sc, - struct wiifb_burstblankeven *bbe) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKEVEN); - - *reg = ((bbe->bbe_be4 & 0x7ff) << 21) | - ((bbe->bbe_bs4 & 0x1f) << 16) | - ((bbe->bbe_be2 & 0x7ff) << 5) | - (bbe->bbe_bs2 & 0x1f); - powerpc_sync(); -} - -/* - * Top Field Base Left - * 32 bit - */ -#define WIIFB_REG_TOPFIELDBASEL 0x1c -struct wiifb_topfieldbasel { - uint32_t tfbl_fbaddr; - uint8_t tfbl_xoffset; - uint8_t tfbl_pageoffbit; -}; - -static __inline void -wiifb_topfieldbasel_read(struct wiifb_softc *sc, - struct wiifb_topfieldbasel *tfbl) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASEL); - - tfbl->tfbl_fbaddr = *reg & 0xffffff; - tfbl->tfbl_xoffset = (*reg >> 24) & 0xf; - tfbl->tfbl_pageoffbit = (*reg >> 28) & 0x1; -} - -static __inline void -wiifb_topfieldbasel_write(struct wiifb_softc *sc, - struct wiifb_topfieldbasel *tfbl) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASEL); - - *reg = ((tfbl->tfbl_pageoffbit & 0x1) << 28) | - ((tfbl->tfbl_xoffset & 0xf) << 24) | - (tfbl->tfbl_fbaddr & 0xffffff); - powerpc_sync(); -} - -/* - * Top Field Base Right - * 32 bit - */ -#define WIIFB_REG_TOPFIELDBASER 0x20 -struct wiifb_topfieldbaser { - uint32_t tfbr_fbaddr; - uint8_t tfbr_pageoffbit; -}; - -static __inline void -wiifb_topfieldbaser_read(struct wiifb_softc *sc, - struct wiifb_topfieldbaser *tfbr) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASER); - - tfbr->tfbr_fbaddr = *reg & 0xffffff; - tfbr->tfbr_pageoffbit = (*reg >> 28) & 0x1; -} - -static __inline void -wiifb_topfieldbaser_write(struct wiifb_softc *sc, - struct wiifb_topfieldbaser *tfbr) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASER); - - *reg = ((tfbr->tfbr_pageoffbit & 0x1) << 28) | - (tfbr->tfbr_fbaddr & 0xffffff); - powerpc_sync(); -} - -/* - * Bottom Field Base Left - * 32 bit - */ -#define WIIFB_REG_BOTTOMFIELDBASEL 0x24 -struct wiifb_bottomfieldbasel { - uint32_t bfbl_fbaddr; - uint8_t bfbl_xoffset; - uint8_t bfbl_pageoffbit; -}; - -static __inline void -wiifb_bottomfieldbasel_read(struct wiifb_softc *sc, - struct wiifb_bottomfieldbasel *bfbl) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASEL); - - bfbl->bfbl_fbaddr = *reg & 0xffffff; - bfbl->bfbl_xoffset = (*reg >> 24) & 0xf; - bfbl->bfbl_pageoffbit = (*reg >> 28) & 0x1; -} - -static __inline void -wiifb_bottomfieldbasel_write(struct wiifb_softc *sc, - struct wiifb_bottomfieldbasel *bfbl) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASEL); - - *reg = ((bfbl->bfbl_pageoffbit & 0x1) << 28) | - ((bfbl->bfbl_xoffset & 0xf) << 24) | - (bfbl->bfbl_fbaddr & 0xffffff); - powerpc_sync(); -} - -/* - * Bottom Field Base Right - * 32 bit - */ -#define WIIFB_REG_BOTTOMFIELDBASER 0x28 -struct wiifb_bottomfieldbaser { - uint32_t bfbr_fbaddr; - uint8_t bfbr_pageoffbit; -}; - -static __inline void -wiifb_bottomfieldbaser_read(struct wiifb_softc *sc, - struct wiifb_bottomfieldbaser *bfbr) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASER); - - bfbr->bfbr_fbaddr = *reg & 0xffffff; - bfbr->bfbr_pageoffbit = (*reg >> 28) & 0x1; -} - -static __inline void -wiifb_bottomfieldbaser_write(struct wiifb_softc *sc, - struct wiifb_bottomfieldbaser *bfbr) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASER); - - *reg = ((bfbr->bfbr_pageoffbit & 0x1) << 28) | - (bfbr->bfbr_fbaddr & 0xffffff); - powerpc_sync(); -} - -/* - * Display Position Vertical - * 16 bit - */ -#define WIIFB_REG_DISPPOSV 0x2c -static __inline uint16_t -wiifb_dispposv_read(struct wiifb_softc *sc) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSV); - - return (*reg & 0x7ff); -} - -static __inline void -wiifb_dispposv_write(struct wiifb_softc *sc, uint16_t val) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSV); - - *reg = val & 0x7ff; - powerpc_sync(); -} - -/* - * Display Position Horizontal - * 16 bit - */ -#define WIIFB_REG_DISPPOSH 0x2e -static __inline uint16_t -wiifb_dispposh_read(struct wiifb_softc *sc) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSH); - - return (*reg & 0x7ff); -} - -static __inline void -wiifb_dispposh_write(struct wiifb_softc *sc, uint16_t val) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSH); - - *reg = val & 0x7ff; - powerpc_sync(); -} - -/* - * Display Interrupts. - * There are 4 display interrupt registers, all 32 bit. - */ -#define WIIFB_REG_DISPINT0 0x30 -#define WIIFB_REG_DISPINT1 0x34 -#define WIIFB_REG_DISPINT2 0x38 -#define WIIFB_REG_DISPINT3 0x3c -struct wiifb_dispint { - uint16_t di_htiming; - uint16_t di_vtiming; - uint8_t di_enable; - uint8_t di_irq; -}; - -static __inline void -wiifb_dispint_read(struct wiifb_softc *sc, int regno, struct wiifb_dispint *di) -{ - volatile uint32_t *reg = (uint32_t *)(sc->sc_reg_addr + - WIIFB_REG_DISPINT0 + regno * 4); - - di->di_htiming = *reg & 0x3ff; - di->di_vtiming = (*reg >> 16) & 0x3ff; - di->di_enable = (*reg >> 28) & 0x1; - di->di_irq = (*reg >> 31) & 0x1; -} - -static __inline void -wiifb_dispint_write(struct wiifb_softc *sc, int regno, struct wiifb_dispint *di) -{ - volatile uint32_t *reg = (uint32_t *)(sc->sc_reg_addr + - WIIFB_REG_DISPINT0 + regno * 4); - - *reg = ((di->di_irq & 0x1) << 31) | - ((di->di_enable & 0x1) << 28) | - ((di->di_vtiming & 0x3ff) << 16) | - (di->di_htiming & 0x3ff); - powerpc_sync(); -} - -/* - * Display Latch 0 - * 32 bit - */ -#define WIIFB_REG_DISPLAYTCH0 0x40 - -/* - * Display Latch 1 - * 32 bit - */ -#define WIIFB_REG_DISPLAYTCH1 0x44 - -/* - * Picture Configuration - * 16 bit - */ -#define WIIFB_REG_PICCONF 0x48 -struct wiifb_picconf { - uint8_t pc_strides; /* strides per line (words) */ - uint8_t pc_reads; /* reads per line (words */ -}; - -static __inline void -wiifb_picconf_read(struct wiifb_softc *sc, struct wiifb_picconf *pc) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_PICCONF); - - pc->pc_strides = *reg & 0xff; - pc->pc_reads = (*reg >> 8) & 0xff; -} - -static __inline void -wiifb_picconf_write(struct wiifb_softc *sc, struct wiifb_picconf *pc) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_PICCONF); - - *reg = ((pc->pc_reads & 0xff) << 8) | - (pc->pc_strides & 0xff); - powerpc_sync(); -} - -/* - * Horizontal Scaling - * 16 bit - */ -#define WIIFB_REG_HSCALING 0x4a -struct wiifb_hscaling { - uint16_t hs_step; - uint8_t hs_enable; -}; - -static __inline void -wiifb_hscaling_read(struct wiifb_softc *sc, struct wiifb_hscaling *hs) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALING); - - hs->hs_step = *reg & 0x1ff; - hs->hs_enable = (*reg >> 12) & 0x1; -} - -static __inline void -wiifb_hscaling_write(struct wiifb_softc *sc, struct wiifb_hscaling *hs) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALING); - - *reg = ((hs->hs_step & 0x1ff) << 12) | - (hs->hs_enable & 0x1); - powerpc_sync(); -} - -/* - * Filter Coeficient Table 0-6 - * 32 bit - */ -#define WIIFB_REG_FILTCOEFT0 0x4c -#define WIIFB_REG_FILTCOEFT1 0x50 -#define WIIFB_REG_FILTCOEFT2 0x54 -#define WIIFB_REG_FILTCOEFT3 0x58 -#define WIIFB_REG_FILTCOEFT4 0x5c -#define WIIFB_REG_FILTCOEFT5 0x60 -#define WIIFB_REG_FILTCOEFT6 0x64 -static __inline void -wiifb_filtcoeft_write(struct wiifb_softc *sc, unsigned int regno, - uint32_t coeft) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_FILTCOEFT0 + 4 * regno); - - *reg = coeft; - powerpc_sync(); -} - -/* - * Anti-aliasing - * 32 bit - */ -#define WIIFB_REG_ANTIALIAS 0x68 -static __inline void -wiifb_antialias_write(struct wiifb_softc *sc, uint32_t antialias) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_ANTIALIAS); - - *reg = antialias; - powerpc_sync(); -} - -/* - * Video Clock - * 16 bit - */ -#define WIIFB_REG_VIDEOCLK 0x6c -static __inline uint8_t -wiifb_videoclk_read(struct wiifb_softc *sc) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VIDEOCLK); - - return (*reg & 0x1); -} - -static __inline void -wiifb_videoclk_write(struct wiifb_softc *sc, uint16_t clk54mhz) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VIDEOCLK); - - *reg = clk54mhz & 0x1; - powerpc_sync(); -} - -/* - * DTV Status - * 16 bit - * - * DTV is another name for the Component Cable output. - */ -#define WIIFB_REG_DTVSTATUS 0x6e -static __inline uint16_t -wiifb_dtvstatus_read(struct wiifb_softc *sc) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_DTVSTATUS); - - return (*reg & 0x1); -} - -static __inline uint16_t -wiifb_component_enabled(struct wiifb_softc *sc) -{ - - return wiifb_dtvstatus_read(sc); -} - -/* - * Horizontal Scaling Width - * 16 bit - */ -#define WIIFB_REG_HSCALINGW 0x70 -static __inline uint16_t -wiifb_hscalingw_read(struct wiifb_softc *sc) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALINGW); - - return (*reg & 0x3ff); -} - -static __inline void -wiifb_hscalingw_write(struct wiifb_softc *sc, uint16_t width) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALINGW); - - *reg = width & 0x3ff; - powerpc_sync(); -} - -/* - * Horizontal Border End - * For debug mode only. Not used by this driver. - * 16 bit - */ -#define WIIFB_REG_HBORDEREND 0x72 -static __inline void -wiifb_hborderend_write(struct wiifb_softc *sc, uint16_t border) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HBORDEREND); - - *reg = border; - powerpc_sync(); -} - -/* - * Horizontal Border Start - * 16 bit - */ -#define WIIFB_REG_HBORDERSTART 0x74 -static __inline void -wiifb_hborderstart_write(struct wiifb_softc *sc, uint16_t border) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HBORDERSTART); - - *reg = border; - powerpc_sync(); -} - -/* - * Unknown register - * 16 bit - */ -#define WIIFB_REG_UNKNOWN1 0x76 -static __inline void -wiifb_unknown1_write(struct wiifb_softc *sc, uint16_t unknown) -{ - volatile uint16_t *reg = - (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_UNKNOWN1); - - *reg = unknown; - powerpc_sync(); -} - -/* - * Unknown register - * 32 bit - */ -#define WIIFB_REG_UNKNOWN2 0x78 -static __inline void -wiifb_unknown2_write(struct wiifb_softc *sc, uint32_t unknown) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_UNKNOWN2); - - *reg = unknown; - powerpc_sync(); -} - -/* - * Unknown register - * 32 bit - */ -#define WIIFB_REG_UNKNOWN3 0x7c -static __inline void -wiifb_unknown3_write(struct wiifb_softc *sc, uint32_t unknown) -{ - volatile uint32_t *reg = - (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_UNKNOWN3); - - *reg = unknown; - powerpc_sync(); -} - -#endif /* _POWERPC_WII_WIIFB_H */ Property changes on: head/sys/powerpc/wii/wii_fbvar.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/locore.S =================================================================== --- head/sys/powerpc/wii/locore.S (revision 278494) +++ head/sys/powerpc/wii/locore.S (nonexistent) @@ -1,131 +0,0 @@ -/*- - * 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 -/* - * 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 FreeBSD. - * - * N.B.: keep the BAT0 in sync with mmu_oea.c and never touch BAT1 later. - * - * This file is being included from aim/locore32.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() Property changes on: head/sys/powerpc/wii/locore.S ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/wii_fbreg.h =================================================================== --- head/sys/powerpc/wii/wii_fbreg.h (revision 278494) +++ head/sys/powerpc/wii/wii_fbreg.h (nonexistent) @@ -1,40 +0,0 @@ -/*- - * 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, - * without modification, immediately at the beginning of the file. - * 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. - * - * $FreeBSD$ - */ - -#ifndef _POWERPC_WII_WII_FBREG_H -#define _POWERPC_WII_WII_FBREG_H - -/* - * Memory addresses for the I/O and the framebuffer. - */ -#define WIIFB_REG_ADDR 0x0c002000 -#define WIIFB_REG_LEN 0x100 -#define WIIFB_FB_ADDR 0x01698000 /* at the end of 1T SRAM */ -#define WIIFB_FB_LEN 0x168000 - -#endif /* _POWERPC_WII_WII_FBREG_H */ Property changes on: head/sys/powerpc/wii/wii_fbreg.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/wii_gpio.c =================================================================== --- head/sys/powerpc/wii/wii_gpio.c (revision 278494) +++ head/sys/powerpc/wii/wii_gpio.c (nonexistent) @@ -1,353 +0,0 @@ -/*- - * 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 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "gpio_if.h" - -struct wiigpio_softc { - device_t sc_dev; - struct resource *sc_rres; - bus_space_tag_t sc_bt; - bus_space_handle_t sc_bh; - int sc_rrid; - struct mtx sc_mtx; - struct gpio_pin sc_pins[WIIGPIO_NPINS]; -}; - - -#define WIIGPIO_PINBANK(_p) ((_p) / (WIIGPIO_NPINS / 2)) -#define WIIGPIO_PINMASK(_p) (1 << ((_p) % (WIIGPIO_NPINS / 2))) -#define WIIGPIO_LOCK(sc) mtx_lock(&(sc)->sc_mtx) -#define WIIGPIO_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) - -static int wiigpio_probe(device_t); -static int wiigpio_attach(device_t); -static int wiigpio_detach(device_t); -static int wiigpio_pin_max(device_t, int *); -static int wiigpio_pin_getname(device_t, uint32_t, char *); -static int wiigpio_pin_getflags(device_t, uint32_t, uint32_t *); -static int wiigpio_pin_setflags(device_t, uint32_t, uint32_t); -static int wiigpio_pin_getcaps(device_t, uint32_t, uint32_t *); -static int wiigpio_pin_get(device_t, uint32_t, unsigned int *); -static int wiigpio_pin_set(device_t, uint32_t, unsigned int); -static int wiigpio_pin_toggle(device_t, uint32_t); -static void wiigpio_shutdown(void *, int); - -static device_method_t wiigpio_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, wiigpio_probe), - DEVMETHOD(device_attach, wiigpio_attach), - DEVMETHOD(device_detach, wiigpio_detach), - - /* GPIO protocol */ - DEVMETHOD(gpio_pin_max, wiigpio_pin_max), - DEVMETHOD(gpio_pin_getname, wiigpio_pin_getname), - DEVMETHOD(gpio_pin_getflags, wiigpio_pin_getflags), - DEVMETHOD(gpio_pin_setflags, wiigpio_pin_setflags), - DEVMETHOD(gpio_pin_getcaps, wiigpio_pin_getcaps), - DEVMETHOD(gpio_pin_get, wiigpio_pin_get), - DEVMETHOD(gpio_pin_set, wiigpio_pin_set), - DEVMETHOD(gpio_pin_toggle, wiigpio_pin_toggle), - - DEVMETHOD_END -}; - -static driver_t wiigpio_driver = { - "wiigpio", - wiigpio_methods, - sizeof(struct wiigpio_softc) -}; - -static devclass_t wiigpio_devclass; - -DRIVER_MODULE(wiigpio, wiibus, wiigpio_driver, wiigpio_devclass, 0, 0); - -static __inline uint32_t -wiigpio_read(struct wiigpio_softc *sc, int n) -{ - - return (bus_space_read_4(sc->sc_bt, sc->sc_bh, n * 0x20)); -} - -static __inline void -wiigpio_write(struct wiigpio_softc *sc, int n, uint32_t reg) -{ - - bus_space_write_4(sc->sc_bt, sc->sc_bh, n * 0x20, reg); -} - -static __inline uint32_t -wiigpio_dir_read(struct wiigpio_softc *sc, int n) -{ - - return (bus_space_read_4(sc->sc_bt, sc->sc_bh, n * 0x20 + 4)); -} - -static __inline void -wiigpio_dir_write(struct wiigpio_softc *sc, int n, uint32_t reg) -{ - - bus_space_write_4(sc->sc_bt, sc->sc_bh, n * 0x20 + 4, reg); -} - -static int -wiigpio_probe(device_t dev) -{ - device_set_desc(dev, "Nintendo Wii GPIO"); - - return (BUS_PROBE_NOWILDCARD); -} - -static int -wiigpio_attach(device_t dev) -{ - struct wiigpio_softc *sc; - int i; - uint32_t d; - - sc = device_get_softc(dev); - sc->sc_dev = dev; - sc->sc_rrid = 0; - sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &sc->sc_rrid, RF_ACTIVE); - if (sc->sc_rres == NULL) { - device_printf(dev, "could not alloc mem resource\n"); - return (ENXIO); - } - sc->sc_bt = rman_get_bustag(sc->sc_rres); - sc->sc_bh = rman_get_bushandle(sc->sc_rres); - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); -#ifdef WIIGPIO_DEBUG - device_printf(dev, "dir bank0=0x%08x bank1=0x%08x\n", - wiigpio_dir_read(sc, 0), wiigpio_dir_read(sc, 1)); - device_printf(dev, "val bank0=0x%08x bank1=0x%08x\n", - wiigpio_read(sc, 0), wiigpio_read(sc, 1)); -#endif - for (i = 0; i < WIIGPIO_NPINS; i++) { - sc->sc_pins[i].gp_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; - sc->sc_pins[i].gp_pin = i; - d = wiigpio_dir_read(sc, WIIGPIO_PINBANK(i)); - if (d & WIIGPIO_PINMASK(i)) - sc->sc_pins[i].gp_flags = GPIO_PIN_OUTPUT; - else - sc->sc_pins[i].gp_flags = GPIO_PIN_INPUT; - snprintf(sc->sc_pins[i].gp_name, GPIOMAXNAME, "PIN %d", i); -#ifdef WIIGPIO_DEBUG - device_printf(dev, "PIN %d state %d flag %s\n", i, - wiigpio_read(sc, WIIGPIO_PINBANK(i)) >> - (i % (WIIGPIO_NPINS / 2)) & 1, - sc->sc_pins[i].gp_flags == GPIO_PIN_INPUT ? - "GPIO_PIN_INPUT" : "GPIO_PIN_OUTPUT"); -#endif - } - device_add_child(dev, "gpioc", -1); - device_add_child(dev, "gpiobus", -1); - /* - * We will be responsible for powering off the system. - */ - EVENTHANDLER_REGISTER(shutdown_final, wiigpio_shutdown, dev, - SHUTDOWN_PRI_LAST); - - return (bus_generic_attach(dev)); -} - -static int -wiigpio_detach(device_t dev) -{ - struct wiigpio_softc *sc; - - sc = device_get_softc(dev); - bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres); - mtx_destroy(&sc->sc_mtx); - - return (0); -} - -static int -wiigpio_pin_max(device_t dev, int *maxpin) -{ - - *maxpin = WIIGPIO_NPINS - 1; - - return (0); -} - -static int -wiigpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) -{ - struct wiigpio_softc *sc; - - if (pin >= WIIGPIO_NPINS) - return (EINVAL); - sc = device_get_softc(dev); - *caps = sc->sc_pins[pin].gp_caps; - - return (0); -} - -static int -wiigpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) -{ - struct wiigpio_softc *sc; - uint32_t reg; - - if (pin >= WIIGPIO_NPINS) - return (EINVAL); - sc = device_get_softc(dev); - WIIGPIO_LOCK(sc); - reg = wiigpio_read(sc, WIIGPIO_PINBANK(pin)); - *val = !!(reg & WIIGPIO_PINMASK(pin)); - WIIGPIO_UNLOCK(sc); - - return (0); -} - -static int -wiigpio_pin_set(device_t dev, uint32_t pin, unsigned int value) -{ - struct wiigpio_softc *sc; - uint32_t reg, pinbank, pinmask; - - if (pin >= WIIGPIO_NPINS) - return (EINVAL); - sc = device_get_softc(dev); - pinbank = WIIGPIO_PINBANK(pin); - pinmask = WIIGPIO_PINMASK(pin); - WIIGPIO_LOCK(sc); - reg = wiigpio_read(sc, pinbank) & ~pinmask; - if (value) - reg |= pinmask; - wiigpio_write(sc, pinbank, reg); - WIIGPIO_UNLOCK(sc); - - return (0); -} - -static int -wiigpio_pin_toggle(device_t dev, uint32_t pin) -{ - struct wiigpio_softc *sc; - uint32_t val, pinbank, pinmask; - - if (pin >= WIIGPIO_NPINS) - return (EINVAL); - sc = device_get_softc(dev); - pinbank = WIIGPIO_PINBANK(pin); - pinmask = WIIGPIO_PINMASK(pin); - WIIGPIO_LOCK(sc); - val = wiigpio_read(sc, pinbank); - if (val & pinmask) - wiigpio_write(sc, pinbank, val & ~pinmask); - else - wiigpio_write(sc, pinbank, val | pinmask); - WIIGPIO_UNLOCK(sc); - - return (0); -} - -static int -wiigpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) -{ - struct wiigpio_softc *sc; - uint32_t reg, pinbank, pinmask; - - if (pin >= WIIGPIO_NPINS) - return (EINVAL); - sc = device_get_softc(dev); - pinbank = WIIGPIO_PINBANK(pin); - pinmask = WIIGPIO_PINMASK(pin); - WIIGPIO_LOCK(sc); - reg = wiigpio_dir_read(sc, WIIGPIO_PINBANK(pin)); - if (flags & GPIO_PIN_OUTPUT) - wiigpio_dir_write(sc, pinbank, reg | pinmask); - else - wiigpio_dir_write(sc, pinbank, reg & ~pinmask); - sc->sc_pins[pin].gp_flags = flags; - WIIGPIO_UNLOCK(sc); - - return (0); -} - -static int -wiigpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) -{ - struct wiigpio_softc *sc; - - if (pin >= WIIGPIO_NPINS) - return (EINVAL); - sc = device_get_softc(dev); - WIIGPIO_LOCK(sc); - *flags = sc->sc_pins[pin].gp_flags; - WIIGPIO_UNLOCK(sc); - - return (0); -} - -static int -wiigpio_pin_getname(device_t dev, uint32_t pin, char *name) -{ - struct wiigpio_softc *sc; - - if (pin >= WIIGPIO_NPINS) - return (EINVAL); - sc = device_get_softc(dev); - WIIGPIO_LOCK(sc); - memcpy(name, sc->sc_pins[pin].gp_name, GPIOMAXNAME); - WIIGPIO_UNLOCK(sc); - - return (0); -} - -static void -wiigpio_shutdown(void *xdev, int howto) -{ - device_t dev; - - if (!(howto & RB_POWEROFF)) - return; - dev = (device_t)xdev; - wiigpio_pin_setflags(dev, WIIGPIO_POWEROFF_PIN, GPIO_PIN_OUTPUT); - wiigpio_pin_set(dev, WIIGPIO_POWEROFF_PIN, 1); -} Property changes on: head/sys/powerpc/wii/wii_gpio.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/wii_fb.c =================================================================== --- head/sys/powerpc/wii/wii_fb.c (revision 278494) +++ head/sys/powerpc/wii/wii_fb.c (nonexistent) @@ -1,885 +0,0 @@ -/*- - * Copyright (C) 2012 Margarida Gouveia - * Copyright (c) 2003 Peter Grehan - * 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, - * without modification, immediately at the beginning of the file. - * 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include - -/* - * Driver for the Nintendo Wii's framebuffer. Based on Linux's gcnfb.c. - */ - -/* - * Syscons glue. - */ -static int wiifb_scprobe(device_t); -static int wiifb_scattach(device_t); - -static device_method_t wiifb_sc_methods[] = { - DEVMETHOD(device_probe, wiifb_scprobe), - DEVMETHOD(device_attach, wiifb_scattach), - - DEVMETHOD_END -}; - -static driver_t wiifb_sc_driver = { - "wiifb", - wiifb_sc_methods, - sizeof(sc_softc_t), -}; - -static devclass_t sc_devclass; - -DRIVER_MODULE(sc, wiibus, wiifb_sc_driver, sc_devclass, 0, 0); - -static int -wiifb_scprobe(device_t dev) -{ - int error; - - device_set_desc(dev, "Nintendo Wii frambuffer"); - - error = sc_probe_unit(device_get_unit(dev), - device_get_flags(dev) | SC_AUTODETECT_KBD); - if (error != 0) - return (error); - - /* This is a fake device, so make sure we added it ourselves */ - return (BUS_PROBE_NOWILDCARD); -} - -static int -wiifb_scattach(device_t dev) -{ - - return (sc_attach_unit(device_get_unit(dev), - device_get_flags(dev) | SC_AUTODETECT_KBD)); -} - -/* - * Video driver routines and glue. - */ -static void wiifb_reset_video(struct wiifb_softc *); -static void wiifb_enable_interrupts(struct wiifb_softc *); -static void wiifb_configure_tv_mode(struct wiifb_softc *); -static void wiifb_setup_framebuffer(struct wiifb_softc *); -static int wiifb_configure(int); -static vi_probe_t wiifb_probe; -static vi_init_t wiifb_init; -static vi_get_info_t wiifb_get_info; -static vi_query_mode_t wiifb_query_mode; -static vi_set_mode_t wiifb_set_mode; -static vi_save_font_t wiifb_save_font; -static vi_load_font_t wiifb_load_font; -static vi_show_font_t wiifb_show_font; -static vi_save_palette_t wiifb_save_palette; -static vi_load_palette_t wiifb_load_palette; -static vi_set_border_t wiifb_set_border; -static vi_save_state_t wiifb_save_state; -static vi_load_state_t wiifb_load_state; -static vi_set_win_org_t wiifb_set_win_org; -static vi_read_hw_cursor_t wiifb_read_hw_cursor; -static vi_set_hw_cursor_t wiifb_set_hw_cursor; -static vi_set_hw_cursor_shape_t wiifb_set_hw_cursor_shape; -static vi_blank_display_t wiifb_blank_display; -static vi_mmap_t wiifb_mmap; -static vi_ioctl_t wiifb_ioctl; -static vi_clear_t wiifb_clear; -static vi_fill_rect_t wiifb_fill_rect; -static vi_bitblt_t wiifb_bitblt; -static vi_diag_t wiifb_diag; -static vi_save_cursor_palette_t wiifb_save_cursor_palette; -static vi_load_cursor_palette_t wiifb_load_cursor_palette; -static vi_copy_t wiifb_copy; -static vi_putp_t wiifb_putp; -static vi_putc_t wiifb_putc; -static vi_puts_t wiifb_puts; -static vi_putm_t wiifb_putm; - -static video_switch_t wiifbvidsw = { - .probe = wiifb_probe, - .init = wiifb_init, - .get_info = wiifb_get_info, - .query_mode = wiifb_query_mode, - .set_mode = wiifb_set_mode, - .save_font = wiifb_save_font, - .load_font = wiifb_load_font, - .show_font = wiifb_show_font, - .save_palette = wiifb_save_palette, - .load_palette = wiifb_load_palette, - .set_border = wiifb_set_border, - .save_state = wiifb_save_state, - .load_state = wiifb_load_state, - .set_win_org = wiifb_set_win_org, - .read_hw_cursor = wiifb_read_hw_cursor, - .set_hw_cursor = wiifb_set_hw_cursor, - .set_hw_cursor_shape = wiifb_set_hw_cursor_shape, - .blank_display = wiifb_blank_display, - .mmap = wiifb_mmap, - .ioctl = wiifb_ioctl, - .clear = wiifb_clear, - .fill_rect = wiifb_fill_rect, - .bitblt = wiifb_bitblt, - .diag = wiifb_diag, - .save_cursor_palette = wiifb_save_cursor_palette, - .load_cursor_palette = wiifb_load_cursor_palette, - .copy = wiifb_copy, - .putp = wiifb_putp, - .putc = wiifb_putc, - .puts = wiifb_puts, - .putm = wiifb_putm, -}; - -VIDEO_DRIVER(wiifb, wiifbvidsw, wiifb_configure); - -extern sc_rndr_sw_t txtrndrsw; -RENDERER(wiifb, 0, txtrndrsw, gfb_set); -RENDERER_MODULE(wiifb, gfb_set); - -static struct wiifb_softc wiifb_softc; -static uint16_t wiifb_static_window[ROW*COL]; -extern u_char dflt_font_8[]; - -/* - * Map the syscons colors to YUY2 (Y'UV422). - * Some colours are an approximation. - * - * The Wii has a 16 bit pixel, so each 32 bit DWORD encodes - * two pixels. The upper 16 bits is for pixel 0 (left hand pixel - * in a pair), the lower 16 bits is for pixel 1. - * - * For now, we're going to ignore that entirely and just use the - * lower 16 bits for each pixel. We'll take the upper value into - * account later. - */ -static uint32_t wiifb_cmap[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 */ -}; - -static struct wiifb_mode_desc wiifb_modes[] = { - [WIIFB_MODE_NTSC_480i] = { - "NTSC 480i", - 640, 480, - 525, - WIIFB_MODE_FLAG_INTERLACED, - }, - [WIIFB_MODE_NTSC_480p] = { - "NTSC 480p", - 640, 480, - 525, - WIIFB_MODE_FLAG_PROGRESSIVE, - }, - [WIIFB_MODE_PAL_576i] = { - "PAL 576i (50Hz)", - 640, 574, - 625, - WIIFB_MODE_FLAG_INTERLACED, - }, - [WIIFB_MODE_PAL_480i] = { - "PAL 480i (60Hz)", - 640, 480, - 525, - WIIFB_MODE_FLAG_INTERLACED, - }, - [WIIFB_MODE_PAL_480p] = { - "PAL 480p", - 640, 480, - 525, - WIIFB_MODE_FLAG_PROGRESSIVE, - }, -}; - -static const uint32_t wiifb_filter_coeft[] = { - 0x1ae771f0, 0x0db4a574, 0x00c1188e, 0xc4c0cbe2, 0xfcecdecf, - 0x13130f08, 0x00080c0f -}; - -static __inline int -wiifb_background(uint8_t attr) -{ - - return (attr >> 4); -} - -static __inline int -wiifb_foreground(uint8_t attr) -{ - - return (attr & 0x0f); -} - -static void -wiifb_reset_video(struct wiifb_softc *sc) -{ - struct wiifb_dispcfg dc; - - wiifb_dispcfg_read(sc, &dc); - dc.dc_reset = 1; - wiifb_dispcfg_write(sc, &dc); - dc.dc_reset = 0; - wiifb_dispcfg_write(sc, &dc); -} - -static void -wiifb_enable_interrupts(struct wiifb_softc *sc) -{ - struct wiifb_dispint di; - -#ifdef notyet - /* - * Display Interrupt 0 - */ - di.di_htiming = 1; - di.di_vtiming = 1; - di.di_enable = 1; - di.di_irq = 1; - wiifb_dispint_write(sc, 0, &di); - - /* - * Display Interrupt 1 - */ - di.di_htiming = sc->sc_format == WIIFB_FORMAT_PAL ? 433 : 430; - di.di_vtiming = sc->sc_mode->fd_lines; - di.di_enable = 1; - di.di_irq = 1; - if (sc->sc_mode->fd_flags & WIIFB_MODE_FLAG_INTERLACED) - di.di_vtiming /= 2; - wiifb_dispint_write(sc, 1, &di); - - /* - * Display Interrupts 2 and 3 are not used. - */ - memset(&di, 0, sizeof(di)); - wiifb_dispint_write(sc, 2, &di); - wiifb_dispint_write(sc, 3, &di); -#else - memset(&di, 0, sizeof(di)); - wiifb_dispint_write(sc, 0, &di); - wiifb_dispint_write(sc, 1, &di); - wiifb_dispint_write(sc, 2, &di); - wiifb_dispint_write(sc, 3, &di); -#endif -} - -/* - * Reference gcnfb.c for an in depth explanation. - * XXX only works with NTSC. - */ -static void -wiifb_configure_tv_mode(struct wiifb_softc *sc) -{ - struct wiifb_vtiming vt; - struct wiifb_hscaling hs; - struct wiifb_htiming0 ht0; - struct wiifb_htiming1 ht1; - struct wiifb_vtimingodd vto; - struct wiifb_vtimingeven vte; - struct wiifb_burstblankodd bbo; - struct wiifb_burstblankeven bbe; - struct wiifb_picconf pc; - struct wiifb_mode_desc *mode = sc->sc_mode; - unsigned int height = mode->fd_height; - unsigned int width = mode->fd_width; - unsigned int eqpulse, interlacebias, shift; - const unsigned int maxwidth = 714; - unsigned int hblanking = maxwidth - width; - unsigned int hmargin = hblanking / 2; - unsigned int A = 20 + hmargin, C = 60 + hblanking - hmargin; - unsigned int maxheight = 484; - unsigned int P = 2 * (20 - 10 + 1); - unsigned int Q = 1; - unsigned int vblanking = maxheight - height; - unsigned int vmargin = vblanking / 2; - unsigned int prb = vmargin; - unsigned int psb = vblanking - vmargin; - int i; - - /* - * Vertical timing. - */ - if (mode->fd_flags & WIIFB_MODE_FLAG_INTERLACED) { - vt.vt_actvideo = height / 2; - interlacebias = 1; - shift = 0; - } else { - vt.vt_actvideo = height; - interlacebias = 0; - shift = 1; - } - /* Lines of equalization */ - if (mode->fd_lines == 625) - eqpulse = 2 * 2.5; - else - eqpulse = 2 * 3; - vt.vt_eqpulse = eqpulse << shift; - wiifb_vtiming_write(sc, &vt); - - /* - * Horizontal timings. - */ - ht0.ht0_hlinew = 858 / 2; - ht1.ht1_hsyncw = 64; - ht0.ht0_hcolourstart = 71; - ht0.ht0_hcolourend = 71 + 34; - ht1.ht1_hblankstart = (858 / 2) - A; - ht1.ht1_hblankend = 64 + C; - wiifb_htiming0_write(sc, &ht0); - wiifb_htiming1_write(sc, &ht1); - - /* - * Vertical timing odd/even. - */ - if (vmargin & 1) { - vto.vto_preb = (P + interlacebias + prb) << shift; - vto.vto_postb = (Q - interlacebias + psb) << shift; - vte.vte_preb = (P + prb) << shift; - vte.vte_postb = (Q - psb) << shift; - } else { - /* XXX if this isn't 0, it doesn't work? */ - prb = 0; - psb = 0; - vte.vte_preb = (P + interlacebias + prb) << shift; - vte.vte_postb = (Q - interlacebias + psb) << shift; - vto.vto_preb = (P + prb) << shift; - vto.vto_postb = (Q - psb) << shift; - } - wiifb_vtimingodd_write(sc, &vto); - wiifb_vtimingeven_write(sc, &vte); - - /* - * Burst blanking odd/even interval. - */ - bbo.bbo_bs1 = 2 * (18 - 7 + 1); - bbe.bbe_bs2 = bbo.bbo_bs3 = bbe.bbe_bs4 = bbo.bbo_bs1; - bbo.bbo_be1 = 2 * (525 - 7 + 1); - bbe.bbe_be2 = bbo.bbo_be3 = bbe.bbe_be4 = bbo.bbo_be1; - wiifb_burstblankodd_write(sc, &bbo); - wiifb_burstblankeven_write(sc, &bbe); - - /* - * Picture configuration. - */ - pc.pc_strides = (mode->fd_width * 2) / 32; - if (mode->fd_flags & WIIFB_MODE_FLAG_INTERLACED) - pc.pc_strides *= 2; - pc.pc_reads = (mode->fd_width * 2) / 32; - wiifb_picconf_write(sc, &pc); - - /* - * Horizontal scaling disabled. - */ - hs.hs_enable = 0; - hs.hs_step = 256; - wiifb_hscaling_write(sc, &hs); - - /* - * Filter coeficient table. - */ - for (i = 0; i < 7; i++) - wiifb_filtcoeft_write(sc, i, wiifb_filter_coeft[i]); - - /* - * Anti alias. - */ - wiifb_antialias_write(sc, 0x00ff0000); - - /* - * Video clock. - */ - wiifb_videoclk_write(sc, - mode->fd_flags & WIIFB_MODE_FLAG_INTERLACED ? 0 : 1); - - /* - * Disable horizontal scaling width. - */ - wiifb_hscalingw_write(sc, mode->fd_width); - - /* - * DEBUG mode borders. Not used. - */ - wiifb_hborderend_write(sc, 0); - wiifb_hborderstart_write(sc, 0); - - /* - * XXX unknown registers. - */ - wiifb_unknown1_write(sc, 0x00ff); - wiifb_unknown2_write(sc, 0x00ff00ff); - wiifb_unknown3_write(sc, 0x00ff00ff); -} - -static void -wiifb_setup_framebuffer(struct wiifb_softc *sc) -{ - intptr_t addr = sc->sc_fb_addr; - struct wiifb_topfieldbasel tfbl; - struct wiifb_bottomfieldbasel bfbl; - struct wiifb_topfieldbaser tfbr; - struct wiifb_bottomfieldbaser bfbr; - - tfbl.tfbl_fbaddr = addr >> 5; - tfbl.tfbl_xoffset = (addr / 2) & 0xf; - tfbl.tfbl_pageoffbit = 1; - wiifb_topfieldbasel_write(sc, &tfbl); - - if (sc->sc_mode->fd_flags & WIIFB_MODE_FLAG_INTERLACED) - addr += sc->sc_mode->fd_width * 2; - bfbl.bfbl_fbaddr = addr >> 5; - bfbl.bfbl_xoffset = (addr / 2) & 0xf; - bfbl.bfbl_pageoffbit = 1; - wiifb_bottomfieldbasel_write(sc, &bfbl); - - /* - * Only used used for 3D. - */ - memset(&tfbr, 0, sizeof(tfbr)); - memset(&bfbr, 0, sizeof(bfbr)); - wiifb_topfieldbaser_write(sc, &tfbr); - wiifb_bottomfieldbaser_write(sc, &bfbr); -} - -static int -wiifb_configure(int flags) -{ - struct wiifb_softc *sc; - struct wiifb_dispcfg dc; - int progressive; - - sc = &wiifb_softc; - if (sc->sc_initialized) { - /* XXX We should instead use bus_space */ - sc->sc_fb_addr = (intptr_t)pmap_mapdev(WIIFB_FB_ADDR, WIIFB_FB_LEN); - sc->sc_reg_addr = (intptr_t)pmap_mapdev(WIIFB_REG_ADDR, WIIFB_REG_LEN); - return 0; - } - - sc->sc_console = 1; - - sc->sc_fb_addr = WIIFB_FB_ADDR; - sc->sc_fb_size = WIIFB_FB_LEN; - - sc->sc_reg_addr = WIIFB_REG_ADDR; - sc->sc_reg_size = WIIFB_REG_LEN; - - wiifb_reset_video(sc); - wiifb_dispcfg_read(sc, &dc); - sc->sc_format = dc.dc_format; - sc->sc_component = wiifb_component_enabled(sc); - progressive = dc.dc_noninterlaced; - switch (sc->sc_format) { - case WIIFB_FORMAT_MPAL: - case WIIFB_FORMAT_DEBUG: - case WIIFB_FORMAT_NTSC: - sc->sc_mode = progressive ? - &wiifb_modes[WIIFB_MODE_NTSC_480p] : - &wiifb_modes[WIIFB_MODE_NTSC_480i]; - break; - case WIIFB_FORMAT_PAL: - sc->sc_mode = progressive ? - &wiifb_modes[WIIFB_MODE_PAL_480p] : - &wiifb_modes[WIIFB_MODE_PAL_480i]; - break; - } - sc->sc_height = sc->sc_mode->fd_height; - sc->sc_width = sc->sc_mode->fd_width; - /* Usually we multiply by 4, but I think this looks better. */ - sc->sc_stride = sc->sc_width * 2; - - wiifb_init(0, &sc->sc_va, 0); - - sc->sc_initialized = 1; - - return (0); -} - -static int -wiifb_probe(int unit, video_adapter_t **adp, void *arg, int flags) -{ - - return (0); -} - -static int -wiifb_init(int unit, video_adapter_t *adp, int flags) -{ - struct wiifb_softc *sc; - video_info_t *vi; - - sc = (struct wiifb_softc *)adp; - vi = &adp->va_info; - - vid_init_struct(adp, "wiifb", -1, unit); - - sc->sc_font = dflt_font_8; - vi->vi_cheight = WIIFB_FONT_HEIGHT; - vi->vi_width = sc->sc_width/8; - vi->vi_height = sc->sc_height/vi->vi_cheight; - vi->vi_cwidth = 8; - - /* - * Clamp width/height to syscons maximums - */ - if (vi->vi_width > COL) - vi->vi_width = COL; - if (vi->vi_height > ROW) - vi->vi_height = ROW; - - sc->sc_xmargin = (sc->sc_width - (vi->vi_width * vi->vi_cwidth)) / 2; - sc->sc_ymargin = (sc->sc_height - (vi->vi_height * vi->vi_cheight))/2; - - adp->va_window = (vm_offset_t) wiifb_static_window; - /* XXX no colour support */ - adp->va_flags |= V_ADP_FONT | /*V_ADP_COLOR |*/ V_ADP_MODECHANGE; - - vid_register(&sc->sc_va); - - wiifb_configure_tv_mode(sc); - wiifb_setup_framebuffer(sc); - wiifb_enable_interrupts(sc); - wiifb_clear(adp); - - return (0); -} - -static int -wiifb_get_info(video_adapter_t *adp, int mode, video_info_t *info) -{ - - bcopy(&adp->va_info, info, sizeof(*info)); - return (0); -} - -static int -wiifb_query_mode(video_adapter_t *adp, video_info_t *info) -{ - - return (0); -} - -static int -wiifb_set_mode(video_adapter_t *adp, int mode) -{ - - return (0); -} - -static int -wiifb_save_font(video_adapter_t *adp, int page, int size, int width, - u_char *data, int c, int count) -{ - - return (0); -} - -static int -wiifb_load_font(video_adapter_t *adp, int page, int size, int width, - u_char *data, int c, int count) -{ - struct wiifb_softc *sc = (struct wiifb_softc *)adp; - - sc->sc_font = data; - - return (0); -} - -static int -wiifb_show_font(video_adapter_t *adp, int page) -{ - - return (0); -} - -static int -wiifb_save_palette(video_adapter_t *adp, u_char *palette) -{ - - return (0); -} - -static int -wiifb_load_palette(video_adapter_t *adp, u_char *palette) -{ - - return (0); -} - -static int -wiifb_set_border(video_adapter_t *adp, int border) -{ - - return (wiifb_blank_display(adp, border)); -} - -static int -wiifb_save_state(video_adapter_t *adp, void *p, size_t size) -{ - - return (0); -} - -static int -wiifb_load_state(video_adapter_t *adp, void *p) -{ - - return (0); -} - -static int -wiifb_set_win_org(video_adapter_t *adp, off_t offset) -{ - - return (0); -} - -static int -wiifb_read_hw_cursor(video_adapter_t *adp, int *col, int *row) -{ - - *col = *row = 0; - - return (0); -} - -static int -wiifb_set_hw_cursor(video_adapter_t *adp, int col, int row) -{ - - return (0); -} - -static int -wiifb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height, - int celsize, int blink) -{ - - return (0); -} - -static int -wiifb_blank_display(video_adapter_t *adp, int mode) -{ - struct wiifb_softc *sc = (struct wiifb_softc *)adp; - uint32_t *p; - - for (p = (uint32_t *)sc->sc_fb_addr; - p < (uint32_t *)(sc->sc_fb_addr + sc->sc_fb_size); - p++) - *p = wiifb_cmap[wiifb_background(SC_NORM_ATTR)]; - - return (0); -} - -static int -wiifb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr, - int prot, vm_memattr_t *memattr) -{ - struct wiifb_softc *sc; - - sc = (struct wiifb_softc *)adp; - - /* - * This might be a legacy VGA mem request: if so, just point it at the - * framebuffer, since it shouldn't be touched - */ - if (offset < sc->sc_stride*sc->sc_height) { - *paddr = sc->sc_fb_addr + offset; - return (0); - } - - return (EINVAL); -} - -static int -wiifb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data) -{ - - return (0); -} - -static int -wiifb_clear(video_adapter_t *adp) -{ - - return (wiifb_blank_display(adp, 0)); -} - -static int -wiifb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) -{ - - return (0); -} - -static int -wiifb_bitblt(video_adapter_t *adp, ...) -{ - - return (0); -} - -static int -wiifb_diag(video_adapter_t *adp, int level) -{ - - return (0); -} - -static int -wiifb_save_cursor_palette(video_adapter_t *adp, u_char *palette) -{ - - return (0); -} - -static int -wiifb_load_cursor_palette(video_adapter_t *adp, u_char *palette) -{ - - return (0); -} - -static int -wiifb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n) -{ - - return (0); -} - -static int -wiifb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a, - int size, int bpp, int bit_ltor, int byte_ltor) -{ - - return (0); -} - -static int -wiifb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a) -{ - struct wiifb_softc *sc; - int row; - int col; - int i, j, k; - uint32_t *addr; - u_char *p; - uint32_t fg, bg; - unsigned long pixel[2]; - - sc = (struct wiifb_softc *)adp; - row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight; - col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth / 2; - p = sc->sc_font + c*WIIFB_FONT_HEIGHT; - addr = (uint32_t *)sc->sc_fb_addr - + (row + sc->sc_ymargin)*(sc->sc_stride/4) - + col + sc->sc_xmargin; - - bg = wiifb_cmap[wiifb_background(a)]; - fg = wiifb_cmap[wiifb_foreground(a)]; - - for (i = 0; i < WIIFB_FONT_HEIGHT; i++) { - for (j = 0, k = 7; j < 4; j++, k--) { - if ((p[i] & (1 << k)) == 0) - pixel[0] = bg; - else - pixel[0] = fg; - k--; - if ((p[i] & (1 << k)) == 0) - pixel[1] = bg; - else - pixel[1] = fg; - - addr[j] = (pixel[0] & 0xffff00ff) | - (pixel[1] & 0x0000ff00); - } - addr += (sc->sc_stride/4); - } - - return (0); -} - -static int -wiifb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len) -{ - int i; - - for (i = 0; i < len; i++) - wiifb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8); - - return (0); -} - -static int -wiifb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image, - uint32_t pixel_mask, int size, int width) -{ - - return (0); -} Property changes on: head/sys/powerpc/wii/wii_fb.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/wii_ipc.c =================================================================== --- head/sys/powerpc/wii/wii_ipc.c (revision 278494) +++ head/sys/powerpc/wii/wii_ipc.c (nonexistent) @@ -1,102 +0,0 @@ -/*- - * 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 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -/* - * Driver to interface with the Wii's IOS. IOS are small "microkernels" that run - * on the Broadway GPU and provide access to system services like USB. - */ -static int wiiipc_probe(device_t); -static int wiiipc_attach(device_t); - -struct wiiipc_softc { -}; - -static device_method_t wiiipc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, wiiipc_probe), - DEVMETHOD(device_attach, wiiipc_attach), - - DEVMETHOD_END -}; - -static driver_t wiiipc_driver = { - "wiiipc", - wiiipc_methods, - sizeof(struct wiiipc_softc) -}; - -static devclass_t wiiipc_devclass; - -DRIVER_MODULE(wiiipc, wiibus, wiiipc_driver, wiiipc_devclass, 0, 0); - -static int -wiiipc_probe(device_t dev) -{ - device_set_desc(dev, "Nintendo Wii IOS IPC"); - - return (BUS_PROBE_NOWILDCARD); -} - -static int -wiiipc_attach(device_t dev) -{ - struct wiiipc_softc *sc; - - sc = device_get_softc(dev); -#ifdef notyet - sc->sc_dev = dev; - - sc->sc_rrid = 0; - sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &sc->sc_rrid, RF_ACTIVE); - if (sc->sc_rres == NULL) { - device_printf(dev, "could not alloc mem resource\n"); - return (ENXIO); - } - sc->sc_bt = rman_get_bustag(sc->sc_rres); - sc->sc_bh = rman_get_bushandle(sc->sc_rres); -#endif - - return (0); -} Property changes on: head/sys/powerpc/wii/wii_ipc.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/wii_picreg.h =================================================================== --- head/sys/powerpc/wii/wii_picreg.h (revision 278494) +++ head/sys/powerpc/wii/wii_picreg.h (nonexistent) @@ -1,42 +0,0 @@ -/*- - * 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 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. - * - * $FreeBSD$ - */ - -#ifndef _POWERPC_WII_WII_PICREG_H -#define _POWERPC_WII_WII_PICREG_H - -#define WIIPIC_REG_ADDR 0x0c003000 -#define WIIPIC_REG_LEN 0x28 - -#define WIIPIC_ICR 0x00 -#define WIIPIC_RBS 0x10000 -#define WIIPIC_IMR 0x04 -#define WIIPIC_RESET 0x24 - -#define WIIPIC_NIRQ 32 - -#endif /* _POWERPC_WII_WII_PICREG_H */ Property changes on: head/sys/powerpc/wii/wii_picreg.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/wii_bus.c =================================================================== --- head/sys/powerpc/wii/wii_bus.c (revision 278494) +++ head/sys/powerpc/wii/wii_bus.c (nonexistent) @@ -1,340 +0,0 @@ -/*- - * 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, - * without modification, immediately at the beginning of the file. - * 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define WIIBUS_CSR_ADDR 0x0d800100 -#define WIIBUS_CSR_LEN 0x300 -#define WIIBUS_CSR_RESET 0x94 - -struct wiibus_softc { - device_t sc_dev; - struct rman sc_rman; - bus_space_tag_t sc_tag; - bus_space_handle_t sc_handle; -}; - -static struct wiibus_softc *wiibus_sc = NULL; - -static uint32_t wiibus_csr_read(struct wiibus_softc *, uint16_t); -static void wiibus_csr_write(struct wiibus_softc *, uint16_t, uint32_t); -static void wiibus_identify(driver_t *, device_t); -static int wiibus_probe(device_t); -static int wiibus_attach(device_t); -static int wiibus_print_child(device_t, device_t); -static struct resource * - wiibus_alloc_resource(device_t, device_t, int, int *, - unsigned long, unsigned long, unsigned long, - unsigned int); -static int wiibus_activate_resource(device_t, device_t, int, int, - struct resource *); - void wiibus_reset_system(void); - -static device_method_t wiibus_methods[] = { - /* Device interface */ - DEVMETHOD(device_identify, wiibus_identify), - DEVMETHOD(device_probe, wiibus_probe), - DEVMETHOD(device_attach, wiibus_attach), - - /* Bus interface */ - DEVMETHOD(bus_add_child, bus_generic_add_child), - DEVMETHOD(bus_print_child, wiibus_print_child), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - DEVMETHOD(bus_alloc_resource, wiibus_alloc_resource), - DEVMETHOD(bus_activate_resource,wiibus_activate_resource), - - DEVMETHOD_END -}; - -static MALLOC_DEFINE(M_WIIBUS, "wiibus", "Nintendo Wii system bus"); - -struct wiibus_devinfo { - struct resource_list di_resources; - uint8_t di_init; -}; - -static driver_t wiibus_driver = { - "wiibus", - wiibus_methods, - sizeof(struct wiibus_softc) -}; - -static devclass_t wiibus_devclass; - -DRIVER_MODULE(wiibus, nexus, wiibus_driver, wiibus_devclass, 0, 0); - -static uint32_t -wiibus_csr_read(struct wiibus_softc *sc, uint16_t reg) -{ - - return (bus_space_read_4(sc->sc_tag, sc->sc_handle, reg)); -} - -static void -wiibus_csr_write(struct wiibus_softc *sc, uint16_t reg, - uint32_t val) -{ - - bus_space_write_4(sc->sc_tag, sc->sc_handle, reg, val); -} - -static void -wiibus_identify(driver_t *driver, device_t parent) -{ - - if (strcmp(installed_platform(), "wii") != 0) - return; - - if (device_find_child(parent, "wiibus", -1) == NULL) - BUS_ADD_CHILD(parent, 0, "wiibus", 0); -} - - -static int -wiibus_probe(device_t dev) -{ - - device_set_desc(dev, "Nintendo Wii System Bus"); - - return (BUS_PROBE_NOWILDCARD); -} - -static void -wiibus_init_device_resources(struct rman *rm, struct wiibus_devinfo *dinfo, - unsigned int rid, uintptr_t addr, size_t len, unsigned int irq) - -{ - - if (!dinfo->di_init) { - resource_list_init(&dinfo->di_resources); - dinfo->di_init++; - } - if (addr) { - rman_manage_region(rm, addr, addr + len - 1); - resource_list_add(&dinfo->di_resources, SYS_RES_MEMORY, rid, - addr, addr + len, len); - } - if (irq) - resource_list_add(&dinfo->di_resources, SYS_RES_IRQ, rid, - irq, irq, 1); -} - -static int -wiibus_attach(device_t self) -{ - struct wiibus_softc *sc; - struct wiibus_devinfo *dinfo; - device_t cdev; - - sc = device_get_softc(self); - sc->sc_rman.rm_type = RMAN_ARRAY; - sc->sc_rman.rm_descr = "Wii Bus Memory Mapped I/O"; - rman_init(&sc->sc_rman); - KASSERT(wiibus_sc == NULL, ("wiibus_sc already initialised")); - wiibus_sc = sc; - - /* Nintendo PIC */ - dinfo = malloc(sizeof(*dinfo), M_WIIBUS, M_WAITOK | M_ZERO); - wiibus_init_device_resources(&sc->sc_rman, dinfo, 0, WIIPIC_REG_ADDR, - WIIPIC_REG_LEN, 1); - cdev = BUS_ADD_CHILD(self, 0, "wiipic", 0); - device_set_ivars(cdev, dinfo); - - /* Framebuffer */ - dinfo = malloc(sizeof(*dinfo), M_WIIBUS, M_WAITOK | M_ZERO); - wiibus_init_device_resources(&sc->sc_rman, dinfo, 0, WIIFB_REG_ADDR, - WIIFB_REG_LEN, 8); - wiibus_init_device_resources(&sc->sc_rman, dinfo, 1, WIIFB_FB_ADDR, - WIIFB_FB_LEN, 0); - cdev = BUS_ADD_CHILD(self, 0, "wiifb", 0); - device_set_ivars(cdev, dinfo); - - /* External Interface Bus */ - dinfo = malloc(sizeof(*dinfo), M_WIIBUS, M_WAITOK | M_ZERO); - wiibus_init_device_resources(&sc->sc_rman, dinfo, 0, WIIEXI_REG_ADDR, - WIIEXI_REG_LEN, 4); - cdev = BUS_ADD_CHILD(self, 0, "wiiexi", 0); - device_set_ivars(cdev, dinfo); - - /* Nintendo IOS IPC */ - dinfo = malloc(sizeof(*dinfo), M_WIIBUS, M_WAITOK | M_ZERO); - wiibus_init_device_resources(&sc->sc_rman, dinfo, 0, WIIIPC_REG_ADDR, - WIIIPC_REG_LEN, 14); - wiibus_init_device_resources(&sc->sc_rman, dinfo, 1, WIIIPC_IOH_ADDR, - WIIIPC_IOH_LEN, 0); - cdev = BUS_ADD_CHILD(self, 0, "wiiipc", 0); - device_set_ivars(cdev, dinfo); - - /* GPIO */ - dinfo = malloc(sizeof(*dinfo), M_WIIBUS, M_WAITOK | M_ZERO); - wiibus_init_device_resources(&sc->sc_rman, dinfo, 0, WIIGPIO_REG_ADDR, - WIIGPIO_REG_LEN, 0); - cdev = BUS_ADD_CHILD(self, 0, "wiigpio", 0); - device_set_ivars(cdev, dinfo); - - /* The control registers */ - sc->sc_tag = &bs_be_tag; - sc->sc_handle = (bus_space_handle_t)pmap_mapdev(WIIBUS_CSR_ADDR, - WIIBUS_CSR_LEN); - - return (bus_generic_attach(self)); -} - -static int -wiibus_print_child(device_t dev, device_t child) -{ - struct wiibus_devinfo *dinfo = device_get_ivars(child); - int retval = 0; - - retval += bus_print_child_header(dev, child); - retval += resource_list_print_type(&dinfo->di_resources, "mem", - SYS_RES_MEMORY, "%#lx"); - retval += resource_list_print_type(&dinfo->di_resources, "irq", - SYS_RES_IRQ, "%ld"); - retval += bus_print_child_footer(dev, child); - - return (retval); -} - -static struct resource * -wiibus_alloc_resource(device_t bus, device_t child, int type, - int *rid, unsigned long start, unsigned long end, - unsigned long count, unsigned int flags) -{ - struct wiibus_softc *sc; - struct wiibus_devinfo *dinfo; - struct resource_list_entry *rle; - struct resource *rv; - int needactivate; - - sc = device_get_softc(bus); - dinfo = device_get_ivars(child); - needactivate = flags & RF_ACTIVE; - flags &= ~RF_ACTIVE; - - switch (type) { - case SYS_RES_MEMORY: - rle = resource_list_find(&dinfo->di_resources, SYS_RES_MEMORY, - *rid); - if (rle == NULL) { - device_printf(bus, "no res entry for %s memory 0x%x\n", - device_get_nameunit(child), *rid); - return (NULL); - } - rv = rman_reserve_resource(&sc->sc_rman, rle->start, rle->end, - rle->count, flags, child); - if (rv == NULL) { - device_printf(bus, - "failed to reserve resource for %s\n", - device_get_nameunit(child)); - return (NULL); - } - rman_set_rid(rv, *rid); - break; - case SYS_RES_IRQ: - return (resource_list_alloc(&dinfo->di_resources, bus, child, - type, rid, start, end, count, flags)); - default: - device_printf(bus, "unknown resource request from %s\n", - device_get_nameunit(child)); - return (NULL); - } - - if (needactivate) { - if (bus_activate_resource(child, type, *rid, rv) != 0) { - device_printf(bus, - "failed to activate resource for %s\n", - device_get_nameunit(child)); - return (NULL); - } - } - - return (rv); -} - -static int -wiibus_activate_resource(device_t bus, device_t child, int type, int rid, - struct resource *res) -{ - void *p; - - switch (type) { - case SYS_RES_MEMORY: - p = pmap_mapdev(rman_get_start(res), rman_get_size(res)); - if (p == NULL) - return (ENOMEM); - rman_set_virtual(res, p); - rman_set_bustag(res, &bs_be_tag); - rman_set_bushandle(res, (unsigned long)p); - break; - case SYS_RES_IRQ: - return (bus_activate_resource(bus, type, rid, res)); - default: - device_printf(bus, - "unknown activate resource request from %s\n", - device_get_nameunit(child)); - return (ENXIO); - } - - return (rman_activate_resource(res)); -} - -void -wiibus_reset_system(void) -{ - uint32_t r; - - r = wiibus_csr_read(wiibus_sc, WIIBUS_CSR_RESET); - r &= ~1; - wiibus_csr_write(wiibus_sc, WIIBUS_CSR_RESET, r); -} Property changes on: head/sys/powerpc/wii/wii_bus.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/wii/wii_pic.c =================================================================== --- head/sys/powerpc/wii/wii_pic.c (revision 278494) +++ head/sys/powerpc/wii/wii_pic.c (nonexistent) @@ -1,244 +0,0 @@ -/*- - * 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 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "pic_if.h" - -static int wiipic_probe(device_t); -static int wiipic_attach(device_t); -static void wiipic_dispatch(device_t, struct trapframe *); -static void wiipic_enable(device_t, unsigned int, unsigned int); -static void wiipic_eoi(device_t, unsigned int); -static void wiipic_mask(device_t, unsigned int); -static void wiipic_unmask(device_t, unsigned int); -static void wiipic_intr(void *); - -struct wiipic_softc { - device_t sc_dev; - struct resource *sc_rres; - bus_space_tag_t sc_bt; - bus_space_handle_t sc_bh; - int sc_rrid; - int sc_irqid; - struct resource *sc_irq; - void *sc_irqctx; - int sc_vector[WIIPIC_NIRQ]; -}; - -static device_method_t wiipic_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, wiipic_probe), - DEVMETHOD(device_attach, wiipic_attach), - - /* PIC interface */ - DEVMETHOD(pic_dispatch, wiipic_dispatch), - DEVMETHOD(pic_enable, wiipic_enable), - DEVMETHOD(pic_eoi, wiipic_eoi), - DEVMETHOD(pic_mask, wiipic_mask), - DEVMETHOD(pic_unmask, wiipic_unmask), - - DEVMETHOD_END -}; - -static driver_t wiipic_driver = { - "wiipic", - wiipic_methods, - sizeof(struct wiipic_softc) -}; - -static devclass_t wiipic_devclass; - -DRIVER_MODULE(wiipic, wiibus, wiipic_driver, wiipic_devclass, 0, 0); - -static __inline uint32_t -wiipic_imr_read(struct wiipic_softc *sc) -{ - - return (bus_space_read_4(sc->sc_bt, sc->sc_bh, WIIPIC_IMR)); -} - -static __inline void -wiipic_imr_write(struct wiipic_softc *sc, uint32_t imr) -{ - - bus_space_write_4(sc->sc_bt, sc->sc_bh, WIIPIC_IMR, imr); -} - -static __inline uint32_t -wiipic_icr_read(struct wiipic_softc *sc) -{ - - return (bus_space_read_4(sc->sc_bt, sc->sc_bh, WIIPIC_ICR)); -} - -static __inline void -wiipic_icr_write(struct wiipic_softc *sc, uint32_t icr) -{ - - bus_space_write_4(sc->sc_bt, sc->sc_bh, WIIPIC_ICR, icr); -} - -static int -wiipic_probe(device_t dev) -{ - device_set_desc(dev, "Nintendo Wii PIC"); - - return (BUS_PROBE_NOWILDCARD); -} - -static int -wiipic_attach(device_t dev) -{ - struct wiipic_softc *sc; - - sc = device_get_softc(dev); - sc->sc_dev = dev; - - sc->sc_rrid = 0; - sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &sc->sc_rrid, RF_ACTIVE); - if (sc->sc_rres == NULL) { - device_printf(dev, "could not alloc mem resource\n"); - return (ENXIO); - } - sc->sc_bt = rman_get_bustag(sc->sc_rres); - sc->sc_bh = rman_get_bushandle(sc->sc_rres); - - /* Turn off all interrupts */ - wiipic_imr_write(sc, 0x00000000); - wiipic_icr_write(sc, 0xffffffff); - - powerpc_register_pic(dev, 0, WIIPIC_NIRQ, 0, FALSE); - - /* - * Setup the interrupt handler. - */ - sc->sc_irqid = 0; - sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irqid, - RF_ACTIVE); - if (sc->sc_irq == NULL) { - device_printf(dev, "could not alloc IRQ resource\n"); - return (ENXIO); - } - bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC | INTR_MPSAFE, - NULL, wiipic_intr, sc, &sc->sc_irqctx); - - return (0); -} - -static void -wiipic_dispatch(device_t dev, struct trapframe *tf) -{ - struct wiipic_softc *sc; - uint32_t irq; - - sc = device_get_softc(dev); - irq = wiipic_icr_read(sc) & wiipic_imr_read(sc); - if (irq == 0) - return; - irq = ffs(irq) - 1; - KASSERT(irq < WIIPIC_NIRQ, ("bogus irq %d", irq)); - powerpc_dispatch_intr(sc->sc_vector[irq], tf); -} - -static void -wiipic_enable(device_t dev, unsigned int irq, unsigned int vector) -{ - struct wiipic_softc *sc; - - KASSERT(irq < WIIPIC_NIRQ, ("bogus irq %d", irq)); - sc = device_get_softc(dev); - sc->sc_vector[irq] = vector; - wiipic_unmask(dev, irq); -} - -static void -wiipic_eoi(device_t dev, unsigned int irq) -{ - struct wiipic_softc *sc; - uint32_t icr; - - sc = device_get_softc(dev); - icr = wiipic_icr_read(sc); - icr |= (1 << irq); - wiipic_icr_write(sc, icr); -} - -static void -wiipic_mask(device_t dev, unsigned int irq) -{ - struct wiipic_softc *sc; - uint32_t imr; - - sc = device_get_softc(dev); - imr = wiipic_imr_read(sc); - imr &= ~(1 << irq); - wiipic_imr_write(sc, imr); -} - -static void -wiipic_unmask(device_t dev, unsigned int irq) -{ - struct wiipic_softc *sc; - uint32_t imr; - - sc = device_get_softc(dev); - imr = wiipic_imr_read(sc); - imr |= (1 << irq); - wiipic_imr_write(sc, imr); -} - -/* - * Reset button interrupt. - */ -static void -wiipic_intr(void *xsc) -{ - struct wiipic_softc *sc; - - sc = (struct wiipic_softc *)xsc; - if (wiipic_icr_read(sc) & WIIPIC_RBS) - shutdown_nice(RB_AUTOBOOT); -} - Property changes on: head/sys/powerpc/wii/wii_pic.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/aim/locore32.S =================================================================== --- head/sys/powerpc/aim/locore32.S (revision 278494) +++ head/sys/powerpc/aim/locore32.S (revision 278495) @@ -1,167 +1,165 @@ /* $FreeBSD$ */ /* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */ /*- * Copyright (C) 2001 Benno Rice * 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 Benno Rice ``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. */ /*- * 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 "assym.s" #include #include #include #include #include #include "opt_platform.h" /* Locate the per-CPU data structure */ #define GET_CPUINFO(r) \ mfsprg0 r /* * Compiled KERNBASE location and the kernel load address */ .globl kernbase .set kernbase, KERNBASE /* * Globals */ .data .align 3 GLOBAL(__startkernel) .long begin GLOBAL(__endkernel) .long end .align 4 #define TMPSTKSZ 8192 /* 8K temporary stack */ GLOBAL(tmpstk) .space TMPSTKSZ .text .globl btext btext: /* * This symbol is here for the benefit of kvm_mkdb, and is supposed to * mark the start of kernel text. */ .globl kernel_text kernel_text: /* * Startup entry. Note, this must be the first thing in the text * segment! */ .text .globl __start __start: li 8,0 li 9,0x100 mtctr 9 1: dcbf 0,8 icbi 0,8 addi 8,8,0x20 bdnz 1b sync isync -#ifdef WII -#include -#endif + /* Zero bss, in case we were started by something unhelpful */ li 0,0 lis 8,_edata@ha addi 8,8,_edata@l lis 9,_end@ha addi 9,9,_end@l 2: stw 0,0(8) addi 8,8,4 cmplw 8,9 blt 2b lis 1,(tmpstk+TMPSTKSZ-16)@ha addi 1,1,(tmpstk+TMPSTKSZ-16)@l bl powerpc_init mr %r1, %r3 li %r3, 0 stw %r3, 0(%r1) bl mi_startup b OF_exit /* * int setfault() * * Similar to setjmp to setup for handling faults on accesses to user memory. * Any routine using this may only call bcopy, either the form below, * or the (currently used) C code optimized, so it doesn't use any non-volatile * registers. */ .globl setfault setfault: mflr 0 mfcr 12 mfsprg 4,0 lwz 4,TD_PCB(2) /* curthread = r2 */ stw 3,PCB_ONFAULT(4) stw 0,0(3) stw 1,4(3) stw 2,8(3) stmw 12,12(3) xor 3,3,3 blr #include Index: head/sys/powerpc/aim/machdep.c =================================================================== --- head/sys/powerpc/aim/machdep.c (revision 278494) +++ head/sys/powerpc/aim/machdep.c (revision 278495) @@ -1,987 +1,974 @@ /*- * 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. */ /*- * Copyright (C) 2001 Benno Rice * 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 Benno Rice ``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. * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $ */ #include __FBSDID("$FreeBSD$"); #include "opt_compat.h" #include "opt_ddb.h" #include "opt_kstack_pages.h" #include "opt_platform.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef __powerpc64__ #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int cold = 1; #ifdef __powerpc64__ extern int n_slbs; int cacheline_size = 128; #else int cacheline_size = 32; #endif int hw_direct_map = 1; extern void *ap_pcpu; struct pcpu __pcpu[MAXCPU]; static struct trapframe frame0; char machine[] = "powerpc"; SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); static void cpu_startup(void *); SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, CTLFLAG_RD, &cacheline_size, 0, ""); uintptr_t powerpc_init(vm_offset_t, vm_offset_t, vm_offset_t, void *); long Maxmem = 0; long realmem = 0; #ifndef __powerpc64__ struct bat battable[16]; #endif struct kva_md_info kmi; static void cpu_startup(void *dummy) { /* * Initialise the decrementer-based clock. */ decr_init(); /* * Good {morning,afternoon,evening,night}. */ cpu_setup(PCPU_GET(cpuid)); #ifdef PERFMON perfmon_init(); #endif printf("real memory = %ld (%ld MB)\n", ptoa(physmem), ptoa(physmem) / 1048576); realmem = physmem; if (bootverbose) printf("available KVA = %zd (%zd MB)\n", virtual_end - virtual_avail, (virtual_end - virtual_avail) / 1048576); /* * Display any holes after the first chunk of extended memory. */ if (bootverbose) { int indx; printf("Physical memory chunk(s):\n"); for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { vm_offset_t size1 = phys_avail[indx + 1] - phys_avail[indx]; #ifdef __powerpc64__ printf("0x%016lx - 0x%016lx, %ld bytes (%ld pages)\n", #else printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n", #endif phys_avail[indx], phys_avail[indx + 1] - 1, size1, size1 / PAGE_SIZE); } } vm_ksubmap_init(&kmi); printf("avail memory = %ld (%ld MB)\n", ptoa(vm_cnt.v_free_count), ptoa(vm_cnt.v_free_count) / 1048576); /* * Set up buffers, so they can be used to read disk labels. */ bufinit(); vm_pager_bufferinit(); } extern vm_offset_t __startkernel, __endkernel; extern unsigned char __bss_start[]; extern unsigned char __sbss_start[]; extern unsigned char __sbss_end[]; extern unsigned char _end[]; #ifndef __powerpc64__ /* Bits for running on 64-bit systems in 32-bit mode. */ extern void *testppc64, *testppc64size; extern void *restorebridge, *restorebridgesize; extern void *rfid_patch, *rfi_patch1, *rfi_patch2; extern void *trapcode64; #endif extern void *rstcode, *rstcodeend; extern void *trapcode, *trapcodeend, *trapcode2; extern void *slbtrap, *slbtrapend; extern void *alitrap, *aliend; extern void *dsitrap, *dsiend; extern void *decrint, *decrsize; extern void *extint, *extsize; extern void *dblow, *dbend; extern void *imisstrap, *imisssize; extern void *dlmisstrap, *dlmisssize; extern void *dsmisstrap, *dsmisssize; uintptr_t powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) { struct pcpu *pc; vm_offset_t startkernel, endkernel; void *generictrap; size_t trap_offset, trapsize; vm_offset_t trap; void *kmdp; char *env; register_t msr, scratch; -#ifdef WII - register_t vers; -#endif uint8_t *cache_check; int cacheline_warn; #ifndef __powerpc64__ int ppc64; #endif #ifdef DDB vm_offset_t ksym_start; vm_offset_t ksym_end; #endif kmdp = NULL; trap_offset = 0; cacheline_warn = 0; /* First guess at start/end kernel positions */ startkernel = __startkernel; endkernel = __endkernel; -#ifdef WII - /* - * The Wii loader doesn't pass us any environment so, mdp - * points to garbage at this point. The Wii CPU is a 750CL. - */ - vers = mfpvr(); - if ((vers & 0xfffff0e0) == (MPC750 << 16 | MPC750CL)) - mdp = NULL; -#endif - /* Check for ePAPR loader, which puts a magic value into r6 */ if (mdp == (void *)0x65504150) mdp = NULL; /* * Parse metadata if present and fetch parameters. Must be done * before console is inited so cninit gets the right value of * boothowto. */ if (mdp != NULL) { preload_metadata = mdp; kmdp = preload_search_by_type("elf kernel"); if (kmdp != NULL) { boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); endkernel = ulmax(endkernel, MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t)); #ifdef DDB ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); db_fetch_ksymtab(ksym_start, ksym_end); #endif } } else { bzero(__sbss_start, __sbss_end - __sbss_start); bzero(__bss_start, _end - __bss_start); } /* Store boot environment state */ OF_initial_setup((void *)fdt, NULL, (int (*)(void *))ofentry); /* * Init params/tunables that can be overridden by the loader */ init_param1(); /* * Start initializing proc0 and thread0. */ proc_linkup0(&proc0, &thread0); thread0.td_frame = &frame0; /* * Set up per-cpu data. */ pc = __pcpu; pcpu_init(pc, 0, sizeof(struct pcpu)); pc->pc_curthread = &thread0; #ifdef __powerpc64__ __asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread)); #else __asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread)); #endif pc->pc_cpuid = 0; __asm __volatile("mtsprg 0, %0" :: "r"(pc)); /* * Init mutexes, which we use heavily in PMAP */ mutex_init(); /* * Install the OF client interface */ OF_bootstrap(); /* * Initialize the console before printing anything. */ cninit(); /* * Complain if there is no metadata. */ if (mdp == NULL || kmdp == NULL) { printf("powerpc_init: no loader metadata.\n"); } /* * Init KDB */ kdb_init(); /* Various very early CPU fix ups */ switch (mfpvr() >> 16) { /* * PowerPC 970 CPUs have a misfeature requested by Apple that * makes them pretend they have a 32-byte cacheline. Turn this * off before we measure the cacheline size. */ case IBM970: case IBM970FX: case IBM970MP: case IBM970GX: scratch = mfspr(SPR_HID5); scratch &= ~HID5_970_DCBZ_SIZE_HI; mtspr(SPR_HID5, scratch); break; #ifdef __powerpc64__ case IBMPOWER7: case IBMPOWER7PLUS: case IBMPOWER8: case IBMPOWER8E: /* XXX: get from ibm,slb-size in device tree */ n_slbs = 32; break; #endif } /* * Initialize the interrupt tables and figure out our cache line * size and whether or not we need the 64-bit bridge code. */ /* * Disable translation in case the vector area hasn't been * mapped (G5). Note that no OFW calls can be made until * translation is re-enabled. */ msr = mfmsr(); mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI); /* * Measure the cacheline size using dcbz * * Use EXC_PGM as a playground. We are about to overwrite it * anyway, we know it exists, and we know it is cache-aligned. */ cache_check = (void *)EXC_PGM; for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++) cache_check[cacheline_size] = 0xff; __asm __volatile("dcbz 0,%0":: "r" (cache_check) : "memory"); /* Find the first byte dcbz did not zero to get the cache line size */ for (cacheline_size = 0; cacheline_size < 0x100 && cache_check[cacheline_size] == 0; cacheline_size++); /* Work around psim bug */ if (cacheline_size == 0) { cacheline_warn = 1; cacheline_size = 32; } /* Make sure the kernel icache is valid before we go too much further */ __syncicache((caddr_t)startkernel, endkernel - startkernel); #ifndef __powerpc64__ /* * Figure out whether we need to use the 64 bit PMAP. This works by * executing an instruction that is only legal on 64-bit PPC (mtmsrd), * and setting ppc64 = 0 if that causes a trap. */ ppc64 = 1; bcopy(&testppc64, (void *)EXC_PGM, (size_t)&testppc64size); __syncicache((void *)EXC_PGM, (size_t)&testppc64size); __asm __volatile("\ mfmsr %0; \ mtsprg2 %1; \ \ mtmsrd %0; \ mfsprg2 %1;" : "=r"(scratch), "=r"(ppc64)); if (ppc64) cpu_features |= PPC_FEATURE_64; /* * Now copy restorebridge into all the handlers, if necessary, * and set up the trap tables. */ if (cpu_features & PPC_FEATURE_64) { /* Patch the two instances of rfi -> rfid */ bcopy(&rfid_patch,&rfi_patch1,4); #ifdef KDB /* rfi_patch2 is at the end of dbleave */ bcopy(&rfid_patch,&rfi_patch2,4); #endif /* * Set the common trap entry point to the one that * knows to restore 32-bit operation on execution. */ generictrap = &trapcode64; } else { generictrap = &trapcode; } #else /* powerpc64 */ cpu_features |= PPC_FEATURE_64; generictrap = &trapcode; #endif trapsize = (size_t)&trapcodeend - (size_t)&trapcode; /* * Copy generic handler into every possible trap. Special cases will get * different ones in a minute. */ for (trap = EXC_RST; trap < EXC_LAST; trap += 0x20) bcopy(generictrap, (void *)trap, trapsize); #ifndef __powerpc64__ if (cpu_features & PPC_FEATURE_64) { /* * Copy a code snippet to restore 32-bit bridge mode * to the top of every non-generic trap handler */ trap_offset += (size_t)&restorebridgesize; - bcopy(&restorebridge, (void *)EXC_RST, trap_offset); - bcopy(&restorebridge, (void *)EXC_DSI, trap_offset); - bcopy(&restorebridge, (void *)EXC_ALI, trap_offset); - bcopy(&restorebridge, (void *)EXC_PGM, trap_offset); - bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset); - bcopy(&restorebridge, (void *)EXC_TRC, trap_offset); - bcopy(&restorebridge, (void *)EXC_BPT, trap_offset); + bcopy(&restorebridge, (void *)EXC_RST, trap_offset); + bcopy(&restorebridge, (void *)EXC_DSI, trap_offset); + bcopy(&restorebridge, (void *)EXC_ALI, trap_offset); + bcopy(&restorebridge, (void *)EXC_PGM, trap_offset); + bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset); + bcopy(&restorebridge, (void *)EXC_TRC, trap_offset); + bcopy(&restorebridge, (void *)EXC_BPT, trap_offset); } #endif bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstcodeend - (size_t)&rstcode); #ifdef KDB bcopy(&dblow, (void *)(EXC_MCHK + trap_offset), (size_t)&dbend - (size_t)&dblow); bcopy(&dblow, (void *)(EXC_PGM + trap_offset), (size_t)&dbend - (size_t)&dblow); bcopy(&dblow, (void *)(EXC_TRC + trap_offset), (size_t)&dbend - (size_t)&dblow); bcopy(&dblow, (void *)(EXC_BPT + trap_offset), (size_t)&dbend - (size_t)&dblow); #endif bcopy(&alitrap, (void *)(EXC_ALI + trap_offset), (size_t)&aliend - (size_t)&alitrap); bcopy(&dsitrap, (void *)(EXC_DSI + trap_offset), (size_t)&dsiend - (size_t)&dsitrap); #ifdef __powerpc64__ /* Set TOC base so that the interrupt code can get at it */ *((void **)TRAP_GENTRAP) = &trapcode2; *((register_t *)TRAP_TOCBASE) = toc; bcopy(&slbtrap, (void *)EXC_DSE,(size_t)&slbtrapend - (size_t)&slbtrap); bcopy(&slbtrap, (void *)EXC_ISE,(size_t)&slbtrapend - (size_t)&slbtrap); #else /* G2-specific TLB miss helper handlers */ bcopy(&imisstrap, (void *)EXC_IMISS, (size_t)&imisssize); bcopy(&dlmisstrap, (void *)EXC_DLMISS, (size_t)&dlmisssize); bcopy(&dsmisstrap, (void *)EXC_DSMISS, (size_t)&dsmisssize); #endif __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD); /* * Restore MSR */ mtmsr(msr); - + /* Warn if cachline size was not determined */ if (cacheline_warn == 1) { printf("WARNING: cacheline size undetermined, setting to 32\n"); } /* * Choose a platform module so we can get the physical memory map. */ - + platform_probe_and_attach(); /* * Initialise virtual memory. Use BUS_PROBE_GENERIC priority * in case the platform module had a better idea of what we * should do. */ if (cpu_features & PPC_FEATURE_64) pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); else pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC); pmap_bootstrap(startkernel, endkernel); mtmsr(PSL_KERNSET & ~PSL_EE); /* * Initialize params/tunables that are derived from memsize */ init_param2(physmem); /* * Grab booted kernel's name */ env = kern_getenv("kernelname"); if (env != NULL) { strlcpy(kernelname, env, sizeof(kernelname)); freeenv(env); } /* * Finish setting up thread0. */ thread0.td_pcb = (struct pcb *) ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE - sizeof(struct pcb)) & ~15UL); bzero((void *)thread0.td_pcb, sizeof(struct pcb)); pc->pc_curpcb = thread0.td_pcb; /* Initialise the message buffer. */ msgbufinit(msgbufp, msgbufsize); #ifdef KDB if (boothowto & RB_KDB) kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); #endif return (((uintptr_t)thread0.td_pcb - (sizeof(struct callframe) - 3*sizeof(register_t))) & ~15UL); } void bzero(void *buf, size_t len) { caddr_t p; p = buf; while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { *p++ = 0; len--; } while (len >= sizeof(u_long) * 8) { *(u_long*) p = 0; *((u_long*) p + 1) = 0; *((u_long*) p + 2) = 0; *((u_long*) p + 3) = 0; len -= sizeof(u_long) * 8; *((u_long*) p + 4) = 0; *((u_long*) p + 5) = 0; *((u_long*) p + 6) = 0; *((u_long*) p + 7) = 0; p += sizeof(u_long) * 8; } while (len >= sizeof(u_long)) { *(u_long*) p = 0; len -= sizeof(u_long); p += sizeof(u_long); } while (len) { *p++ = 0; len--; } } void cpu_boot(int howto) { } /* * Flush the D-cache for non-DMA I/O so that the I-cache can * be made coherent later. */ void cpu_flush_dcache(void *ptr, size_t len) { /* TBD */ } /* * Shutdown the CPU as much as possible. */ void cpu_halt(void) { OF_exit(); } int ptrace_set_pc(struct thread *td, unsigned long addr) { struct trapframe *tf; tf = td->td_frame; tf->srr0 = (register_t)addr; return (0); } int ptrace_single_step(struct thread *td) { struct trapframe *tf; - + tf = td->td_frame; tf->srr1 |= PSL_SE; return (0); } int ptrace_clear_single_step(struct thread *td) { struct trapframe *tf; tf = td->td_frame; tf->srr1 &= ~PSL_SE; return (0); } void kdb_cpu_clear_singlestep(void) { kdb_frame->srr1 &= ~PSL_SE; } void kdb_cpu_set_singlestep(void) { kdb_frame->srr1 |= PSL_SE; } /* * Initialise a struct pcpu. */ void cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) { #ifdef __powerpc64__ /* Copy the SLB contents from the current CPU */ memcpy(pcpu->pc_slb, PCPU_GET(slb), sizeof(pcpu->pc_slb)); #endif } void spinlock_enter(void) { struct thread *td; register_t msr; td = curthread; if (td->td_md.md_spinlock_count == 0) { __asm __volatile("or 2,2,2"); /* Set high thread priority */ msr = intr_disable(); td->td_md.md_spinlock_count = 1; td->td_md.md_saved_msr = msr; } else td->td_md.md_spinlock_count++; critical_enter(); } void spinlock_exit(void) { struct thread *td; register_t msr; td = curthread; critical_exit(); msr = td->td_md.md_saved_msr; td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) { intr_restore(msr); __asm __volatile("or 6,6,6"); /* Set normal thread priority */ } } int db_trap_glue(struct trapframe *); /* Called from trap_subr.S */ int db_trap_glue(struct trapframe *frame) { if (!(frame->srr1 & PSL_PR) && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC || (frame->exc == EXC_PGM && (frame->srr1 & 0x20000)) || frame->exc == EXC_BPT || frame->exc == EXC_DSI)) { int type = frame->exc; /* Ignore DTrace traps. */ - if (*(uint32_t *)frame->srr0 == EXC_DTRACE) + if (*(uint32_t *)frame->srr0 == EXC_DTRACE) return (0); if (type == EXC_PGM && (frame->srr1 & 0x20000)) { type = T_BREAKPOINT; } return (kdb_trap(type, 0, frame)); } return (0); } #ifndef __powerpc64__ uint64_t va_to_vsid(pmap_t pm, vm_offset_t va) { return ((pm->pm_sr[(uintptr_t)va >> ADDR_SR_SHFT]) & SR_VSID_MASK); } #endif vm_offset_t pmap_early_io_map(vm_paddr_t pa, vm_size_t size) { return (pa); } /* From p3-53 of the MPC7450 RISC Microprocessor Family Reference Manual */ void flush_disable_caches(void) { register_t msr; register_t msscr0; register_t cache_reg; volatile uint32_t *memp; uint32_t temp; int i; int x; msr = mfmsr(); powerpc_sync(); mtmsr(msr & ~(PSL_EE | PSL_DR)); msscr0 = mfspr(SPR_MSSCR0); msscr0 &= ~MSSCR0_L2PFE; mtspr(SPR_MSSCR0, msscr0); powerpc_sync(); isync(); __asm__ __volatile__("dssall; sync"); powerpc_sync(); isync(); __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); /* Lock the L1 Data cache. */ mtspr(SPR_LDSTCR, mfspr(SPR_LDSTCR) | 0xFF); powerpc_sync(); isync(); mtspr(SPR_LDSTCR, 0); /* * Perform this in two stages: Flush the cache starting in RAM, then do it * from ROM. */ memp = (volatile uint32_t *)0x00000000; for (i = 0; i < 128 * 1024; i++) { temp = *memp; __asm__ __volatile__("dcbf 0,%0" :: "r"(memp)); memp += 32/sizeof(*memp); } memp = (volatile uint32_t *)0xfff00000; x = 0xfe; for (; x != 0xff;) { mtspr(SPR_LDSTCR, x); for (i = 0; i < 128; i++) { temp = *memp; __asm__ __volatile__("dcbf 0,%0" :: "r"(memp)); memp += 32/sizeof(*memp); } x = ((x << 1) | 1) & 0xff; } mtspr(SPR_LDSTCR, 0); cache_reg = mfspr(SPR_L2CR); if (cache_reg & L2CR_L2E) { cache_reg &= ~(L2CR_L2IO_7450 | L2CR_L2DO_7450); mtspr(SPR_L2CR, cache_reg); powerpc_sync(); mtspr(SPR_L2CR, cache_reg | L2CR_L2HWF); while (mfspr(SPR_L2CR) & L2CR_L2HWF) ; /* Busy wait for cache to flush */ powerpc_sync(); cache_reg &= ~L2CR_L2E; mtspr(SPR_L2CR, cache_reg); powerpc_sync(); mtspr(SPR_L2CR, cache_reg | L2CR_L2I); powerpc_sync(); while (mfspr(SPR_L2CR) & L2CR_L2I) ; /* Busy wait for L2 cache invalidate */ powerpc_sync(); } cache_reg = mfspr(SPR_L3CR); if (cache_reg & L3CR_L3E) { cache_reg &= ~(L3CR_L3IO | L3CR_L3DO); mtspr(SPR_L3CR, cache_reg); powerpc_sync(); mtspr(SPR_L3CR, cache_reg | L3CR_L3HWF); while (mfspr(SPR_L3CR) & L3CR_L3HWF) ; /* Busy wait for cache to flush */ powerpc_sync(); cache_reg &= ~L3CR_L3E; mtspr(SPR_L3CR, cache_reg); powerpc_sync(); mtspr(SPR_L3CR, cache_reg | L3CR_L3I); powerpc_sync(); while (mfspr(SPR_L3CR) & L3CR_L3I) ; /* Busy wait for L3 cache invalidate */ powerpc_sync(); } mtspr(SPR_HID0, mfspr(SPR_HID0) & ~HID0_DCE); powerpc_sync(); isync(); mtmsr(msr); } void cpu_sleep() { static u_quad_t timebase = 0; static register_t sprgs[4]; static register_t srrs[2]; jmp_buf resetjb; struct thread *fputd; struct thread *vectd; register_t hid0; register_t msr; register_t saved_msr; ap_pcpu = pcpup; PCPU_SET(restore, &resetjb); saved_msr = mfmsr(); fputd = PCPU_GET(fputhread); vectd = PCPU_GET(vecthread); if (fputd != NULL) save_fpu(fputd); if (vectd != NULL) save_vec(vectd); if (setjmp(resetjb) == 0) { sprgs[0] = mfspr(SPR_SPRG0); sprgs[1] = mfspr(SPR_SPRG1); sprgs[2] = mfspr(SPR_SPRG2); sprgs[3] = mfspr(SPR_SPRG3); srrs[0] = mfspr(SPR_SRR0); srrs[1] = mfspr(SPR_SRR1); timebase = mftb(); powerpc_sync(); flush_disable_caches(); hid0 = mfspr(SPR_HID0); hid0 = (hid0 & ~(HID0_DOZE | HID0_NAP)) | HID0_SLEEP; powerpc_sync(); isync(); msr = mfmsr() | PSL_POW; mtspr(SPR_HID0, hid0); powerpc_sync(); while (1) mtmsr(msr); } mttb(timebase); PCPU_SET(curthread, curthread); PCPU_SET(curpcb, curthread->td_pcb); pmap_activate(curthread); powerpc_sync(); mtspr(SPR_SPRG0, sprgs[0]); mtspr(SPR_SPRG1, sprgs[1]); mtspr(SPR_SPRG2, sprgs[2]); mtspr(SPR_SPRG3, sprgs[3]); mtspr(SPR_SRR0, srrs[0]); mtspr(SPR_SRR1, srrs[1]); mtmsr(saved_msr); if (fputd == curthread) enable_fpu(curthread); if (vectd == curthread) enable_vec(curthread); powerpc_sync(); } Index: head/sys/powerpc/aim/mmu_oea.c =================================================================== --- head/sys/powerpc/aim/mmu_oea.c (revision 278494) +++ head/sys/powerpc/aim/mmu_oea.c (revision 278495) @@ -1,2700 +1,2685 @@ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Matt Thomas of Allegro Networks, Inc. * * 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. * * $NetBSD: pmap.c,v 1.28 2000/03/26 20:42:36 kleink Exp $ */ /*- * Copyright (C) 2001 Benno Rice. * 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 Benno Rice ``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 __FBSDID("$FreeBSD$"); /* * Manages physical address maps. * * Since the information managed by this module is also stored by the * logical address mapping module, this module may throw away valid virtual * to physical mappings at almost any time. However, invalidations of * mappings must be done as requested. * * In order to cope with hardware architectures which make virtual to * physical map invalidates expensive, this module may delay invalidate * reduced protection operations until such time as they are actually * necessary. This module is given full information as to which processors * are currently using which maps, and to when physical maps must be made * correct. */ #include "opt_kstack_pages.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mmu_if.h" #define MOEA_DEBUG #define TODO panic("%s: not implemented", __func__); #define VSID_MAKE(sr, hash) ((sr) | (((hash) & 0xfffff) << 4)) #define VSID_TO_SR(vsid) ((vsid) & 0xf) #define VSID_TO_HASH(vsid) (((vsid) >> 4) & 0xfffff) struct ofw_map { vm_offset_t om_va; vm_size_t om_len; vm_offset_t om_pa; u_int om_mode; }; extern unsigned char _etext[]; extern unsigned char _end[]; /* * Map of physical memory regions. */ static struct mem_region *regions; static struct mem_region *pregions; static u_int phys_avail_count; static int regions_sz, pregions_sz; static struct ofw_map *translations; /* * Lock for the pteg and pvo tables. */ struct mtx moea_table_mutex; struct mtx moea_vsid_mutex; /* tlbie instruction synchronization */ static struct mtx tlbie_mtx; /* * PTEG data. */ static struct pteg *moea_pteg_table; u_int moea_pteg_count; u_int moea_pteg_mask; /* * PVO data. */ struct pvo_head *moea_pvo_table; /* pvo entries by pteg index */ struct pvo_head moea_pvo_kunmanaged = LIST_HEAD_INITIALIZER(moea_pvo_kunmanaged); /* list of unmanaged pages */ static struct rwlock_padalign pvh_global_lock; uma_zone_t moea_upvo_zone; /* zone for pvo entries for unmanaged pages */ uma_zone_t moea_mpvo_zone; /* zone for pvo entries for managed pages */ #define BPVO_POOL_SIZE 32768 static struct pvo_entry *moea_bpvo_pool; static int moea_bpvo_pool_index = 0; #define VSID_NBPW (sizeof(u_int32_t) * 8) static u_int moea_vsid_bitmap[NPMAPS / VSID_NBPW]; static boolean_t moea_initialized = FALSE; /* * Statistics. */ u_int moea_pte_valid = 0; u_int moea_pte_overflow = 0; u_int moea_pte_replacements = 0; u_int moea_pvo_entries = 0; u_int moea_pvo_enter_calls = 0; u_int moea_pvo_remove_calls = 0; u_int moea_pte_spills = 0; SYSCTL_INT(_machdep, OID_AUTO, moea_pte_valid, CTLFLAG_RD, &moea_pte_valid, 0, ""); SYSCTL_INT(_machdep, OID_AUTO, moea_pte_overflow, CTLFLAG_RD, &moea_pte_overflow, 0, ""); SYSCTL_INT(_machdep, OID_AUTO, moea_pte_replacements, CTLFLAG_RD, &moea_pte_replacements, 0, ""); SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_entries, CTLFLAG_RD, &moea_pvo_entries, 0, ""); SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_enter_calls, CTLFLAG_RD, &moea_pvo_enter_calls, 0, ""); SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_remove_calls, CTLFLAG_RD, &moea_pvo_remove_calls, 0, ""); SYSCTL_INT(_machdep, OID_AUTO, moea_pte_spills, CTLFLAG_RD, &moea_pte_spills, 0, ""); /* * Allocate physical memory for use in moea_bootstrap. */ static vm_offset_t moea_bootstrap_alloc(vm_size_t, u_int); /* * PTE calls. */ static int moea_pte_insert(u_int, struct pte *); /* * PVO calls. */ static int moea_pvo_enter(pmap_t, uma_zone_t, struct pvo_head *, vm_offset_t, vm_offset_t, u_int, int); static void moea_pvo_remove(struct pvo_entry *, int); static struct pvo_entry *moea_pvo_find_va(pmap_t, vm_offset_t, int *); static struct pte *moea_pvo_to_pte(const struct pvo_entry *, int); /* * Utility routines. */ static int moea_enter_locked(pmap_t, vm_offset_t, vm_page_t, vm_prot_t, u_int, int8_t); static void moea_syncicache(vm_offset_t, vm_size_t); static boolean_t moea_query_bit(vm_page_t, int); static u_int moea_clear_bit(vm_page_t, int); static void moea_kremove(mmu_t, vm_offset_t); int moea_pte_spill(vm_offset_t); /* * Kernel MMU interface */ void moea_clear_modify(mmu_t, vm_page_t); void moea_copy_page(mmu_t, vm_page_t, vm_page_t); void moea_copy_pages(mmu_t mmu, vm_page_t *ma, vm_offset_t a_offset, vm_page_t *mb, vm_offset_t b_offset, int xfersize); int moea_enter(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t, u_int, int8_t); void moea_enter_object(mmu_t, pmap_t, vm_offset_t, vm_offset_t, vm_page_t, vm_prot_t); void moea_enter_quick(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t); vm_paddr_t moea_extract(mmu_t, pmap_t, vm_offset_t); vm_page_t moea_extract_and_hold(mmu_t, pmap_t, vm_offset_t, vm_prot_t); void moea_init(mmu_t); boolean_t moea_is_modified(mmu_t, vm_page_t); boolean_t moea_is_prefaultable(mmu_t, pmap_t, vm_offset_t); boolean_t moea_is_referenced(mmu_t, vm_page_t); int moea_ts_referenced(mmu_t, vm_page_t); vm_offset_t moea_map(mmu_t, vm_offset_t *, vm_paddr_t, vm_paddr_t, int); boolean_t moea_page_exists_quick(mmu_t, pmap_t, vm_page_t); int moea_page_wired_mappings(mmu_t, vm_page_t); void moea_pinit(mmu_t, pmap_t); void moea_pinit0(mmu_t, pmap_t); void moea_protect(mmu_t, pmap_t, vm_offset_t, vm_offset_t, vm_prot_t); void moea_qenter(mmu_t, vm_offset_t, vm_page_t *, int); void moea_qremove(mmu_t, vm_offset_t, int); void moea_release(mmu_t, pmap_t); void moea_remove(mmu_t, pmap_t, vm_offset_t, vm_offset_t); void moea_remove_all(mmu_t, vm_page_t); void moea_remove_write(mmu_t, vm_page_t); void moea_unwire(mmu_t, pmap_t, vm_offset_t, vm_offset_t); void moea_zero_page(mmu_t, vm_page_t); void moea_zero_page_area(mmu_t, vm_page_t, int, int); void moea_zero_page_idle(mmu_t, vm_page_t); void moea_activate(mmu_t, struct thread *); void moea_deactivate(mmu_t, struct thread *); void moea_cpu_bootstrap(mmu_t, int); void moea_bootstrap(mmu_t, vm_offset_t, vm_offset_t); void *moea_mapdev(mmu_t, vm_paddr_t, vm_size_t); void *moea_mapdev_attr(mmu_t, vm_offset_t, vm_size_t, vm_memattr_t); void moea_unmapdev(mmu_t, vm_offset_t, vm_size_t); vm_paddr_t moea_kextract(mmu_t, vm_offset_t); void moea_kenter_attr(mmu_t, vm_offset_t, vm_offset_t, vm_memattr_t); void moea_kenter(mmu_t, vm_offset_t, vm_paddr_t); void moea_page_set_memattr(mmu_t mmu, vm_page_t m, vm_memattr_t ma); boolean_t moea_dev_direct_mapped(mmu_t, vm_paddr_t, vm_size_t); static void moea_sync_icache(mmu_t, pmap_t, vm_offset_t, vm_size_t); void moea_dumpsys_map(mmu_t mmu, vm_paddr_t pa, size_t sz, void **va); void moea_scan_init(mmu_t mmu); static mmu_method_t moea_methods[] = { MMUMETHOD(mmu_clear_modify, moea_clear_modify), MMUMETHOD(mmu_copy_page, moea_copy_page), MMUMETHOD(mmu_copy_pages, moea_copy_pages), MMUMETHOD(mmu_enter, moea_enter), MMUMETHOD(mmu_enter_object, moea_enter_object), MMUMETHOD(mmu_enter_quick, moea_enter_quick), MMUMETHOD(mmu_extract, moea_extract), MMUMETHOD(mmu_extract_and_hold, moea_extract_and_hold), MMUMETHOD(mmu_init, moea_init), MMUMETHOD(mmu_is_modified, moea_is_modified), MMUMETHOD(mmu_is_prefaultable, moea_is_prefaultable), MMUMETHOD(mmu_is_referenced, moea_is_referenced), MMUMETHOD(mmu_ts_referenced, moea_ts_referenced), MMUMETHOD(mmu_map, moea_map), MMUMETHOD(mmu_page_exists_quick,moea_page_exists_quick), MMUMETHOD(mmu_page_wired_mappings,moea_page_wired_mappings), MMUMETHOD(mmu_pinit, moea_pinit), MMUMETHOD(mmu_pinit0, moea_pinit0), MMUMETHOD(mmu_protect, moea_protect), MMUMETHOD(mmu_qenter, moea_qenter), MMUMETHOD(mmu_qremove, moea_qremove), MMUMETHOD(mmu_release, moea_release), MMUMETHOD(mmu_remove, moea_remove), MMUMETHOD(mmu_remove_all, moea_remove_all), MMUMETHOD(mmu_remove_write, moea_remove_write), MMUMETHOD(mmu_sync_icache, moea_sync_icache), MMUMETHOD(mmu_unwire, moea_unwire), MMUMETHOD(mmu_zero_page, moea_zero_page), MMUMETHOD(mmu_zero_page_area, moea_zero_page_area), MMUMETHOD(mmu_zero_page_idle, moea_zero_page_idle), MMUMETHOD(mmu_activate, moea_activate), MMUMETHOD(mmu_deactivate, moea_deactivate), MMUMETHOD(mmu_page_set_memattr, moea_page_set_memattr), /* Internal interfaces */ MMUMETHOD(mmu_bootstrap, moea_bootstrap), MMUMETHOD(mmu_cpu_bootstrap, moea_cpu_bootstrap), MMUMETHOD(mmu_mapdev_attr, moea_mapdev_attr), MMUMETHOD(mmu_mapdev, moea_mapdev), MMUMETHOD(mmu_unmapdev, moea_unmapdev), MMUMETHOD(mmu_kextract, moea_kextract), MMUMETHOD(mmu_kenter, moea_kenter), MMUMETHOD(mmu_kenter_attr, moea_kenter_attr), MMUMETHOD(mmu_dev_direct_mapped,moea_dev_direct_mapped), MMUMETHOD(mmu_scan_init, moea_scan_init), MMUMETHOD(mmu_dumpsys_map, moea_dumpsys_map), { 0, 0 } }; MMU_DEF(oea_mmu, MMU_TYPE_OEA, moea_methods, 0); static __inline uint32_t moea_calc_wimg(vm_offset_t pa, vm_memattr_t ma) { uint32_t pte_lo; int i; if (ma != VM_MEMATTR_DEFAULT) { switch (ma) { case VM_MEMATTR_UNCACHEABLE: return (PTE_I | PTE_G); case VM_MEMATTR_WRITE_COMBINING: case VM_MEMATTR_WRITE_BACK: case VM_MEMATTR_PREFETCHABLE: return (PTE_I); case VM_MEMATTR_WRITE_THROUGH: return (PTE_W | PTE_M); } } /* * Assume the page is cache inhibited and access is guarded unless * it's in our available memory array. */ pte_lo = PTE_I | PTE_G; for (i = 0; i < pregions_sz; i++) { if ((pa >= pregions[i].mr_start) && (pa < (pregions[i].mr_start + pregions[i].mr_size))) { pte_lo = PTE_M; break; } } return pte_lo; } static void tlbie(vm_offset_t va) { mtx_lock_spin(&tlbie_mtx); __asm __volatile("ptesync"); __asm __volatile("tlbie %0" :: "r"(va)); __asm __volatile("eieio; tlbsync; ptesync"); mtx_unlock_spin(&tlbie_mtx); } static void tlbia(void) { vm_offset_t va; - + for (va = 0; va < 0x00040000; va += 0x00001000) { __asm __volatile("tlbie %0" :: "r"(va)); powerpc_sync(); } __asm __volatile("tlbsync"); powerpc_sync(); } static __inline int va_to_sr(u_int *sr, vm_offset_t va) { return (sr[(uintptr_t)va >> ADDR_SR_SHFT]); } static __inline u_int va_to_pteg(u_int sr, vm_offset_t addr) { u_int hash; hash = (sr & SR_VSID_MASK) ^ (((u_int)addr & ADDR_PIDX) >> ADDR_PIDX_SHFT); return (hash & moea_pteg_mask); } static __inline struct pvo_head * vm_page_to_pvoh(vm_page_t m) { return (&m->md.mdpg_pvoh); } static __inline void moea_attr_clear(vm_page_t m, int ptebit) { rw_assert(&pvh_global_lock, RA_WLOCKED); m->md.mdpg_attrs &= ~ptebit; } static __inline int moea_attr_fetch(vm_page_t m) { return (m->md.mdpg_attrs); } static __inline void moea_attr_save(vm_page_t m, int ptebit) { rw_assert(&pvh_global_lock, RA_WLOCKED); m->md.mdpg_attrs |= ptebit; } static __inline int moea_pte_compare(const struct pte *pt, const struct pte *pvo_pt) { if (pt->pte_hi == pvo_pt->pte_hi) return (1); return (0); } static __inline int moea_pte_match(struct pte *pt, u_int sr, vm_offset_t va, int which) { return (pt->pte_hi & ~PTE_VALID) == (((sr & SR_VSID_MASK) << PTE_VSID_SHFT) | ((va >> ADDR_API_SHFT) & PTE_API) | which); } static __inline void moea_pte_create(struct pte *pt, u_int sr, vm_offset_t va, u_int pte_lo) { mtx_assert(&moea_table_mutex, MA_OWNED); /* * Construct a PTE. Default to IMB initially. Valid bit only gets * set when the real pte is set in memory. * * Note: Don't set the valid bit for correct operation of tlb update. */ pt->pte_hi = ((sr & SR_VSID_MASK) << PTE_VSID_SHFT) | (((va & ADDR_PIDX) >> ADDR_API_SHFT) & PTE_API); pt->pte_lo = pte_lo; } static __inline void moea_pte_synch(struct pte *pt, struct pte *pvo_pt) { mtx_assert(&moea_table_mutex, MA_OWNED); pvo_pt->pte_lo |= pt->pte_lo & (PTE_REF | PTE_CHG); } static __inline void moea_pte_clear(struct pte *pt, vm_offset_t va, int ptebit) { mtx_assert(&moea_table_mutex, MA_OWNED); /* * As shown in Section 7.6.3.2.3 */ pt->pte_lo &= ~ptebit; tlbie(va); } static __inline void moea_pte_set(struct pte *pt, struct pte *pvo_pt) { mtx_assert(&moea_table_mutex, MA_OWNED); pvo_pt->pte_hi |= PTE_VALID; /* * Update the PTE as defined in section 7.6.3.1. * Note that the REF/CHG bits are from pvo_pt and thus should have * been saved so this routine can restore them (if desired). */ pt->pte_lo = pvo_pt->pte_lo; powerpc_sync(); pt->pte_hi = pvo_pt->pte_hi; powerpc_sync(); moea_pte_valid++; } static __inline void moea_pte_unset(struct pte *pt, struct pte *pvo_pt, vm_offset_t va) { mtx_assert(&moea_table_mutex, MA_OWNED); pvo_pt->pte_hi &= ~PTE_VALID; /* * Force the reg & chg bits back into the PTEs. */ powerpc_sync(); /* * Invalidate the pte. */ pt->pte_hi &= ~PTE_VALID; tlbie(va); /* * Save the reg & chg bits. */ moea_pte_synch(pt, pvo_pt); moea_pte_valid--; } static __inline void moea_pte_change(struct pte *pt, struct pte *pvo_pt, vm_offset_t va) { /* * Invalidate the PTE */ moea_pte_unset(pt, pvo_pt, va); moea_pte_set(pt, pvo_pt); } /* * Quick sort callout for comparing memory regions. */ static int om_cmp(const void *a, const void *b); static int om_cmp(const void *a, const void *b) { const struct ofw_map *mapa; const struct ofw_map *mapb; mapa = a; mapb = b; if (mapa->om_pa < mapb->om_pa) return (-1); else if (mapa->om_pa > mapb->om_pa) return (1); else return (0); } void moea_cpu_bootstrap(mmu_t mmup, int ap) { u_int sdr; int i; if (ap) { powerpc_sync(); __asm __volatile("mtdbatu 0,%0" :: "r"(battable[0].batu)); __asm __volatile("mtdbatl 0,%0" :: "r"(battable[0].batl)); isync(); __asm __volatile("mtibatu 0,%0" :: "r"(battable[0].batu)); __asm __volatile("mtibatl 0,%0" :: "r"(battable[0].batl)); isync(); } -#ifdef WII - /* - * Special case for the Wii: don't install the PCI BAT. - */ - if (strcmp(installed_platform(), "wii") != 0) { -#endif - __asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu)); - __asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl)); -#ifdef WII - } -#endif + __asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu)); + __asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl)); isync(); __asm __volatile("mtibatu 1,%0" :: "r"(0)); __asm __volatile("mtdbatu 2,%0" :: "r"(0)); __asm __volatile("mtibatu 2,%0" :: "r"(0)); __asm __volatile("mtdbatu 3,%0" :: "r"(0)); __asm __volatile("mtibatu 3,%0" :: "r"(0)); isync(); for (i = 0; i < 16; i++) mtsrin(i << ADDR_SR_SHFT, kernel_pmap->pm_sr[i]); powerpc_sync(); sdr = (u_int)moea_pteg_table | (moea_pteg_mask >> 10); __asm __volatile("mtsdr1 %0" :: "r"(sdr)); isync(); tlbia(); } void moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend) { ihandle_t mmui; phandle_t chosen, mmu; int sz; int i, j; vm_size_t size, physsz, hwphyssz; vm_offset_t pa, va, off; void *dpcpu; register_t msr; /* * Set up BAT0 to map the lowest 256 MB area */ battable[0x0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW); battable[0x0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs); /* * Map PCI memory space. */ battable[0x8].batl = BATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW); battable[0x8].batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs); battable[0x9].batl = BATL(0x90000000, BAT_I|BAT_G, BAT_PP_RW); battable[0x9].batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs); battable[0xa].batl = BATL(0xa0000000, BAT_I|BAT_G, BAT_PP_RW); battable[0xa].batu = BATU(0xa0000000, BAT_BL_256M, BAT_Vs); battable[0xb].batl = BATL(0xb0000000, BAT_I|BAT_G, BAT_PP_RW); battable[0xb].batu = BATU(0xb0000000, BAT_BL_256M, BAT_Vs); /* * Map obio devices. */ battable[0xf].batl = BATL(0xf0000000, BAT_I|BAT_G, BAT_PP_RW); battable[0xf].batu = BATU(0xf0000000, BAT_BL_256M, BAT_Vs); /* * Use an IBAT and a DBAT to map the bottom segment of memory * where we are. Turn off instruction relocation temporarily * to prevent faults while reprogramming the IBAT. */ msr = mfmsr(); mtmsr(msr & ~PSL_IR); __asm (".balign 32; \n" "mtibatu 0,%0; mtibatl 0,%1; isync; \n" "mtdbatu 0,%0; mtdbatl 0,%1; isync" :: "r"(battable[0].batu), "r"(battable[0].batl)); mtmsr(msr); -#ifdef WII - if (strcmp(installed_platform(), "wii") != 0) { -#endif - /* map pci space */ - __asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu)); - __asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl)); -#ifdef WII - } -#endif + /* map pci space */ + __asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu)); + __asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl)); isync(); /* set global direct map flag */ hw_direct_map = 1; mem_regions(&pregions, &pregions_sz, ®ions, ®ions_sz); CTR0(KTR_PMAP, "moea_bootstrap: physical memory"); for (i = 0; i < pregions_sz; i++) { vm_offset_t pa; vm_offset_t end; CTR3(KTR_PMAP, "physregion: %#x - %#x (%#x)", pregions[i].mr_start, pregions[i].mr_start + pregions[i].mr_size, pregions[i].mr_size); /* * Install entries into the BAT table to allow all * of physmem to be convered by on-demand BAT entries. * The loop will sometimes set the same battable element * twice, but that's fine since they won't be used for * a while yet. */ pa = pregions[i].mr_start & 0xf0000000; end = pregions[i].mr_start + pregions[i].mr_size; do { u_int n = pa >> ADDR_SR_SHFT; battable[n].batl = BATL(pa, BAT_M, BAT_PP_RW); battable[n].batu = BATU(pa, BAT_BL_256M, BAT_Vs); pa += SEGMENT_LENGTH; } while (pa < end); } if (sizeof(phys_avail)/sizeof(phys_avail[0]) < regions_sz) panic("moea_bootstrap: phys_avail too small"); phys_avail_count = 0; physsz = 0; hwphyssz = 0; TUNABLE_ULONG_FETCH("hw.physmem", (u_long *) &hwphyssz); for (i = 0, j = 0; i < regions_sz; i++, j += 2) { CTR3(KTR_PMAP, "region: %#x - %#x (%#x)", regions[i].mr_start, regions[i].mr_start + regions[i].mr_size, regions[i].mr_size); if (hwphyssz != 0 && (physsz + regions[i].mr_size) >= hwphyssz) { if (physsz < hwphyssz) { phys_avail[j] = regions[i].mr_start; phys_avail[j + 1] = regions[i].mr_start + hwphyssz - physsz; physsz = hwphyssz; phys_avail_count++; } break; } phys_avail[j] = regions[i].mr_start; phys_avail[j + 1] = regions[i].mr_start + regions[i].mr_size; phys_avail_count++; physsz += regions[i].mr_size; } /* Check for overlap with the kernel and exception vectors */ for (j = 0; j < 2*phys_avail_count; j+=2) { if (phys_avail[j] < EXC_LAST) phys_avail[j] += EXC_LAST; if (kernelstart >= phys_avail[j] && kernelstart < phys_avail[j+1]) { if (kernelend < phys_avail[j+1]) { phys_avail[2*phys_avail_count] = (kernelend & ~PAGE_MASK) + PAGE_SIZE; phys_avail[2*phys_avail_count + 1] = phys_avail[j+1]; phys_avail_count++; } phys_avail[j+1] = kernelstart & ~PAGE_MASK; } if (kernelend >= phys_avail[j] && kernelend < phys_avail[j+1]) { if (kernelstart > phys_avail[j]) { phys_avail[2*phys_avail_count] = phys_avail[j]; phys_avail[2*phys_avail_count + 1] = kernelstart & ~PAGE_MASK; phys_avail_count++; } phys_avail[j] = (kernelend & ~PAGE_MASK) + PAGE_SIZE; } } physmem = btoc(physsz); /* * Allocate PTEG table. */ #ifdef PTEGCOUNT moea_pteg_count = PTEGCOUNT; #else moea_pteg_count = 0x1000; while (moea_pteg_count < physmem) moea_pteg_count <<= 1; moea_pteg_count >>= 1; #endif /* PTEGCOUNT */ size = moea_pteg_count * sizeof(struct pteg); CTR2(KTR_PMAP, "moea_bootstrap: %d PTEGs, %d bytes", moea_pteg_count, size); moea_pteg_table = (struct pteg *)moea_bootstrap_alloc(size, size); CTR1(KTR_PMAP, "moea_bootstrap: PTEG table at %p", moea_pteg_table); bzero((void *)moea_pteg_table, moea_pteg_count * sizeof(struct pteg)); moea_pteg_mask = moea_pteg_count - 1; /* * Allocate pv/overflow lists. */ size = sizeof(struct pvo_head) * moea_pteg_count; moea_pvo_table = (struct pvo_head *)moea_bootstrap_alloc(size, PAGE_SIZE); CTR1(KTR_PMAP, "moea_bootstrap: PVO table at %p", moea_pvo_table); for (i = 0; i < moea_pteg_count; i++) LIST_INIT(&moea_pvo_table[i]); /* * Initialize the lock that synchronizes access to the pteg and pvo * tables. */ mtx_init(&moea_table_mutex, "pmap table", NULL, MTX_DEF | MTX_RECURSE); mtx_init(&moea_vsid_mutex, "VSID table", NULL, MTX_DEF); mtx_init(&tlbie_mtx, "tlbie", NULL, MTX_SPIN); /* * Initialise the unmanaged pvo pool. */ moea_bpvo_pool = (struct pvo_entry *)moea_bootstrap_alloc( BPVO_POOL_SIZE*sizeof(struct pvo_entry), 0); moea_bpvo_pool_index = 0; /* * Make sure kernel vsid is allocated as well as VSID 0. */ moea_vsid_bitmap[(KERNEL_VSIDBITS & (NPMAPS - 1)) / VSID_NBPW] |= 1 << (KERNEL_VSIDBITS % VSID_NBPW); moea_vsid_bitmap[0] |= 1; /* * Initialize the kernel pmap (which is statically allocated). */ PMAP_LOCK_INIT(kernel_pmap); for (i = 0; i < 16; i++) kernel_pmap->pm_sr[i] = EMPTY_SEGMENT + i; CPU_FILL(&kernel_pmap->pm_active); RB_INIT(&kernel_pmap->pmap_pvo); /* * Initialize the global pv list lock. */ rw_init(&pvh_global_lock, "pmap pv global"); /* * Set up the Open Firmware mappings */ chosen = OF_finddevice("/chosen"); if (chosen != -1 && OF_getprop(chosen, "mmu", &mmui, 4) != -1 && - (mmu = OF_instance_to_package(mmui)) != -1 && + (mmu = OF_instance_to_package(mmui)) != -1 && (sz = OF_getproplen(mmu, "translations")) != -1) { translations = NULL; for (i = 0; phys_avail[i] != 0; i += 2) { if (phys_avail[i + 1] >= sz) { translations = (struct ofw_map *)phys_avail[i]; break; } } if (translations == NULL) panic("moea_bootstrap: no space to copy translations"); bzero(translations, sz); if (OF_getprop(mmu, "translations", translations, sz) == -1) panic("moea_bootstrap: can't get ofw translations"); CTR0(KTR_PMAP, "moea_bootstrap: translations"); sz /= sizeof(*translations); qsort(translations, sz, sizeof (*translations), om_cmp); for (i = 0; i < sz; i++) { CTR3(KTR_PMAP, "translation: pa=%#x va=%#x len=%#x", translations[i].om_pa, translations[i].om_va, translations[i].om_len); /* * If the mapping is 1:1, let the RAM and device * on-demand BAT tables take care of the translation. */ if (translations[i].om_va == translations[i].om_pa) continue; /* Enter the pages */ for (off = 0; off < translations[i].om_len; off += PAGE_SIZE) - moea_kenter(mmup, translations[i].om_va + off, + moea_kenter(mmup, translations[i].om_va + off, translations[i].om_pa + off); } } /* * Calculate the last available physical address. */ for (i = 0; phys_avail[i + 2] != 0; i += 2) ; Maxmem = powerpc_btop(phys_avail[i + 1]); moea_cpu_bootstrap(mmup,0); pmap_bootstrapped++; /* * Set the start and end of kva. */ virtual_avail = VM_MIN_KERNEL_ADDRESS; virtual_end = VM_MAX_SAFE_KERNEL_ADDRESS; /* * Allocate a kernel stack with a guard page for thread0 and map it * into the kernel page map. */ pa = moea_bootstrap_alloc(KSTACK_PAGES * PAGE_SIZE, PAGE_SIZE); va = virtual_avail + KSTACK_GUARD_PAGES * PAGE_SIZE; virtual_avail = va + KSTACK_PAGES * PAGE_SIZE; CTR2(KTR_PMAP, "moea_bootstrap: kstack0 at %#x (%#x)", pa, va); thread0.td_kstack = va; thread0.td_kstack_pages = KSTACK_PAGES; for (i = 0; i < KSTACK_PAGES; i++) { moea_kenter(mmup, va, pa); pa += PAGE_SIZE; va += PAGE_SIZE; } /* * Allocate virtual address space for the message buffer. */ pa = msgbuf_phys = moea_bootstrap_alloc(msgbufsize, PAGE_SIZE); msgbufp = (struct msgbuf *)virtual_avail; va = virtual_avail; virtual_avail += round_page(msgbufsize); while (va < virtual_avail) { moea_kenter(mmup, va, pa); pa += PAGE_SIZE; va += PAGE_SIZE; } /* * Allocate virtual address space for the dynamic percpu area. */ pa = moea_bootstrap_alloc(DPCPU_SIZE, PAGE_SIZE); dpcpu = (void *)virtual_avail; va = virtual_avail; virtual_avail += DPCPU_SIZE; while (va < virtual_avail) { moea_kenter(mmup, va, pa); pa += PAGE_SIZE; va += PAGE_SIZE; } dpcpu_init(dpcpu, 0); } /* * Activate a user pmap. The pmap must be activated before it's address * space can be accessed in any way. */ void moea_activate(mmu_t mmu, struct thread *td) { pmap_t pm, pmr; /* * Load all the data we need up front to encourage the compiler to * not issue any loads while we have interrupts disabled below. */ pm = &td->td_proc->p_vmspace->vm_pmap; pmr = pm->pmap_phys; CPU_SET(PCPU_GET(cpuid), &pm->pm_active); PCPU_SET(curpmap, pmr); } void moea_deactivate(mmu_t mmu, struct thread *td) { pmap_t pm; pm = &td->td_proc->p_vmspace->vm_pmap; CPU_CLR(PCPU_GET(cpuid), &pm->pm_active); PCPU_SET(curpmap, NULL); } void moea_unwire(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva) { struct pvo_entry key, *pvo; PMAP_LOCK(pm); key.pvo_vaddr = sva; for (pvo = RB_NFIND(pvo_tree, &pm->pmap_pvo, &key); pvo != NULL && PVO_VADDR(pvo) < eva; pvo = RB_NEXT(pvo_tree, &pm->pmap_pvo, pvo)) { if ((pvo->pvo_vaddr & PVO_WIRED) == 0) panic("moea_unwire: pvo %p is missing PVO_WIRED", pvo); pvo->pvo_vaddr &= ~PVO_WIRED; pm->pm_stats.wired_count--; } PMAP_UNLOCK(pm); } void moea_copy_page(mmu_t mmu, vm_page_t msrc, vm_page_t mdst) { vm_offset_t dst; vm_offset_t src; dst = VM_PAGE_TO_PHYS(mdst); src = VM_PAGE_TO_PHYS(msrc); bcopy((void *)src, (void *)dst, PAGE_SIZE); } void moea_copy_pages(mmu_t mmu, vm_page_t *ma, vm_offset_t a_offset, vm_page_t *mb, vm_offset_t b_offset, int xfersize) { void *a_cp, *b_cp; vm_offset_t a_pg_offset, b_pg_offset; int cnt; while (xfersize > 0) { a_pg_offset = a_offset & PAGE_MASK; cnt = min(xfersize, PAGE_SIZE - a_pg_offset); a_cp = (char *)VM_PAGE_TO_PHYS(ma[a_offset >> PAGE_SHIFT]) + a_pg_offset; b_pg_offset = b_offset & PAGE_MASK; cnt = min(cnt, PAGE_SIZE - b_pg_offset); b_cp = (char *)VM_PAGE_TO_PHYS(mb[b_offset >> PAGE_SHIFT]) + b_pg_offset; bcopy(a_cp, b_cp, cnt); a_offset += cnt; b_offset += cnt; xfersize -= cnt; } } /* * Zero a page of physical memory by temporarily mapping it into the tlb. */ void moea_zero_page(mmu_t mmu, vm_page_t m) { vm_offset_t off, pa = VM_PAGE_TO_PHYS(m); for (off = 0; off < PAGE_SIZE; off += cacheline_size) __asm __volatile("dcbz 0,%0" :: "r"(pa + off)); } void moea_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size) { vm_offset_t pa = VM_PAGE_TO_PHYS(m); void *va = (void *)(pa + off); bzero(va, size); } void moea_zero_page_idle(mmu_t mmu, vm_page_t m) { moea_zero_page(mmu, m); } /* * Map the given physical page at the specified virtual address in the * target pmap with the protection requested. If specified the page * will be wired down. */ int moea_enter(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, u_int flags, int8_t psind) { int error; for (;;) { rw_wlock(&pvh_global_lock); PMAP_LOCK(pmap); error = moea_enter_locked(pmap, va, m, prot, flags, psind); rw_wunlock(&pvh_global_lock); PMAP_UNLOCK(pmap); if (error != ENOMEM) return (KERN_SUCCESS); if ((flags & PMAP_ENTER_NOSLEEP) != 0) return (KERN_RESOURCE_SHORTAGE); VM_OBJECT_ASSERT_UNLOCKED(m->object); VM_WAIT; } } /* * Map the given physical page at the specified virtual address in the * target pmap with the protection requested. If specified the page * will be wired down. * * The global pvh and pmap must be locked. */ static int moea_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, u_int flags, int8_t psind __unused) { struct pvo_head *pvo_head; uma_zone_t zone; u_int pte_lo, pvo_flags; int error; if (pmap_bootstrapped) rw_assert(&pvh_global_lock, RA_WLOCKED); PMAP_LOCK_ASSERT(pmap, MA_OWNED); if ((m->oflags & VPO_UNMANAGED) == 0 && !vm_page_xbusied(m)) VM_OBJECT_ASSERT_LOCKED(m->object); if ((m->oflags & VPO_UNMANAGED) != 0 || !moea_initialized) { pvo_head = &moea_pvo_kunmanaged; zone = moea_upvo_zone; pvo_flags = 0; } else { pvo_head = vm_page_to_pvoh(m); zone = moea_mpvo_zone; pvo_flags = PVO_MANAGED; } pte_lo = moea_calc_wimg(VM_PAGE_TO_PHYS(m), pmap_page_get_memattr(m)); if (prot & VM_PROT_WRITE) { pte_lo |= PTE_BW; if (pmap_bootstrapped && (m->oflags & VPO_UNMANAGED) == 0) vm_page_aflag_set(m, PGA_WRITEABLE); } else pte_lo |= PTE_BR; if ((flags & PMAP_ENTER_WIRED) != 0) pvo_flags |= PVO_WIRED; error = moea_pvo_enter(pmap, zone, pvo_head, va, VM_PAGE_TO_PHYS(m), pte_lo, pvo_flags); /* * Flush the real page from the instruction cache. This has be done * for all user mappings to prevent information leakage via the * instruction cache. moea_pvo_enter() returns ENOENT for the first * mapping for a page. */ if (pmap != kernel_pmap && error == ENOENT && (pte_lo & (PTE_I | PTE_G)) == 0) moea_syncicache(VM_PAGE_TO_PHYS(m), PAGE_SIZE); return (error); } /* * Maps a sequence of resident pages belonging to the same object. * The sequence begins with the given page m_start. This page is * mapped at the given virtual address start. Each subsequent page is * mapped at a virtual address that is offset from start by the same * amount as the page is offset from m_start within the object. The * last page in the sequence is the page with the largest offset from * m_start that can be mapped at a virtual address less than the given * virtual address end. Not every virtual page between start and end * is mapped; only those for which a resident page exists with the * corresponding offset from m_start are mapped. */ void moea_enter_object(mmu_t mmu, pmap_t pm, vm_offset_t start, vm_offset_t end, vm_page_t m_start, vm_prot_t prot) { vm_page_t m; vm_pindex_t diff, psize; VM_OBJECT_ASSERT_LOCKED(m_start->object); psize = atop(end - start); m = m_start; rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) { moea_enter_locked(pm, start + ptoa(diff), m, prot & (VM_PROT_READ | VM_PROT_EXECUTE), 0, 0); m = TAILQ_NEXT(m, listq); } rw_wunlock(&pvh_global_lock); PMAP_UNLOCK(pm); } void moea_enter_quick(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_page_t m, vm_prot_t prot) { rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); moea_enter_locked(pm, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE), 0, 0); rw_wunlock(&pvh_global_lock); PMAP_UNLOCK(pm); } vm_paddr_t moea_extract(mmu_t mmu, pmap_t pm, vm_offset_t va) { struct pvo_entry *pvo; vm_paddr_t pa; PMAP_LOCK(pm); pvo = moea_pvo_find_va(pm, va & ~ADDR_POFF, NULL); if (pvo == NULL) pa = 0; else pa = (pvo->pvo_pte.pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF); PMAP_UNLOCK(pm); return (pa); } /* * Atomically extract and hold the physical page with the given * pmap and virtual address pair if that mapping permits the given * protection. */ vm_page_t moea_extract_and_hold(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_prot_t prot) { struct pvo_entry *pvo; vm_page_t m; vm_paddr_t pa; m = NULL; pa = 0; PMAP_LOCK(pmap); retry: pvo = moea_pvo_find_va(pmap, va & ~ADDR_POFF, NULL); if (pvo != NULL && (pvo->pvo_pte.pte.pte_hi & PTE_VALID) && ((pvo->pvo_pte.pte.pte_lo & PTE_PP) == PTE_RW || (prot & VM_PROT_WRITE) == 0)) { if (vm_page_pa_tryrelock(pmap, pvo->pvo_pte.pte.pte_lo & PTE_RPGN, &pa)) goto retry; m = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte.pte_lo & PTE_RPGN); vm_page_hold(m); } PA_UNLOCK_COND(pa); PMAP_UNLOCK(pmap); return (m); } void moea_init(mmu_t mmu) { moea_upvo_zone = uma_zcreate("UPVO entry", sizeof (struct pvo_entry), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE); moea_mpvo_zone = uma_zcreate("MPVO entry", sizeof(struct pvo_entry), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE); moea_initialized = TRUE; } boolean_t moea_is_referenced(mmu_t mmu, vm_page_t m) { boolean_t rv; KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("moea_is_referenced: page %p is not managed", m)); rw_wlock(&pvh_global_lock); rv = moea_query_bit(m, PTE_REF); rw_wunlock(&pvh_global_lock); return (rv); } boolean_t moea_is_modified(mmu_t mmu, vm_page_t m) { boolean_t rv; KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("moea_is_modified: page %p is not managed", m)); /* * If the page is not exclusive busied, then PGA_WRITEABLE cannot be * concurrently set while the object is locked. Thus, if PGA_WRITEABLE * is clear, no PTEs can have PTE_CHG set. */ VM_OBJECT_ASSERT_WLOCKED(m->object); if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0) return (FALSE); rw_wlock(&pvh_global_lock); rv = moea_query_bit(m, PTE_CHG); rw_wunlock(&pvh_global_lock); return (rv); } boolean_t moea_is_prefaultable(mmu_t mmu, pmap_t pmap, vm_offset_t va) { struct pvo_entry *pvo; boolean_t rv; PMAP_LOCK(pmap); pvo = moea_pvo_find_va(pmap, va & ~ADDR_POFF, NULL); rv = pvo == NULL || (pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0; PMAP_UNLOCK(pmap); return (rv); } void moea_clear_modify(mmu_t mmu, vm_page_t m) { KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("moea_clear_modify: page %p is not managed", m)); VM_OBJECT_ASSERT_WLOCKED(m->object); KASSERT(!vm_page_xbusied(m), ("moea_clear_modify: page %p is exclusive busy", m)); /* * If the page is not PGA_WRITEABLE, then no PTEs can have PTE_CHG * set. If the object containing the page is locked and the page is * not exclusive busied, then PGA_WRITEABLE cannot be concurrently set. */ if ((m->aflags & PGA_WRITEABLE) == 0) return; rw_wlock(&pvh_global_lock); moea_clear_bit(m, PTE_CHG); rw_wunlock(&pvh_global_lock); } /* * Clear the write and modified bits in each of the given page's mappings. */ void moea_remove_write(mmu_t mmu, vm_page_t m) { struct pvo_entry *pvo; struct pte *pt; pmap_t pmap; u_int lo; KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("moea_remove_write: page %p is not managed", m)); /* * If the page is not exclusive busied, then PGA_WRITEABLE cannot be * set by another thread while the object is locked. Thus, * if PGA_WRITEABLE is clear, no page table entries need updating. */ VM_OBJECT_ASSERT_WLOCKED(m->object); if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0) return; rw_wlock(&pvh_global_lock); lo = moea_attr_fetch(m); powerpc_sync(); LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) { pmap = pvo->pvo_pmap; PMAP_LOCK(pmap); if ((pvo->pvo_pte.pte.pte_lo & PTE_PP) != PTE_BR) { pt = moea_pvo_to_pte(pvo, -1); pvo->pvo_pte.pte.pte_lo &= ~PTE_PP; pvo->pvo_pte.pte.pte_lo |= PTE_BR; if (pt != NULL) { moea_pte_synch(pt, &pvo->pvo_pte.pte); lo |= pvo->pvo_pte.pte.pte_lo; pvo->pvo_pte.pte.pte_lo &= ~PTE_CHG; moea_pte_change(pt, &pvo->pvo_pte.pte, pvo->pvo_vaddr); mtx_unlock(&moea_table_mutex); } } PMAP_UNLOCK(pmap); } if ((lo & PTE_CHG) != 0) { moea_attr_clear(m, PTE_CHG); vm_page_dirty(m); } vm_page_aflag_clear(m, PGA_WRITEABLE); rw_wunlock(&pvh_global_lock); } /* * moea_ts_referenced: * * Return a count of reference bits for a page, clearing those bits. * It is not necessary for every reference bit to be cleared, but it * is necessary that 0 only be returned when there are truly no * reference bits set. * * XXX: The exact number of bits to check and clear is a matter that * should be tested and standardized at some point in the future for * optimal aging of shared pages. */ int moea_ts_referenced(mmu_t mmu, vm_page_t m) { int count; KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("moea_ts_referenced: page %p is not managed", m)); rw_wlock(&pvh_global_lock); count = moea_clear_bit(m, PTE_REF); rw_wunlock(&pvh_global_lock); return (count); } /* * Modify the WIMG settings of all mappings for a page. */ void moea_page_set_memattr(mmu_t mmu, vm_page_t m, vm_memattr_t ma) { struct pvo_entry *pvo; struct pvo_head *pvo_head; struct pte *pt; pmap_t pmap; u_int lo; if ((m->oflags & VPO_UNMANAGED) != 0) { m->md.mdpg_cache_attrs = ma; return; } rw_wlock(&pvh_global_lock); pvo_head = vm_page_to_pvoh(m); lo = moea_calc_wimg(VM_PAGE_TO_PHYS(m), ma); LIST_FOREACH(pvo, pvo_head, pvo_vlink) { pmap = pvo->pvo_pmap; PMAP_LOCK(pmap); pt = moea_pvo_to_pte(pvo, -1); pvo->pvo_pte.pte.pte_lo &= ~PTE_WIMG; pvo->pvo_pte.pte.pte_lo |= lo; if (pt != NULL) { moea_pte_change(pt, &pvo->pvo_pte.pte, pvo->pvo_vaddr); if (pvo->pvo_pmap == kernel_pmap) isync(); } mtx_unlock(&moea_table_mutex); PMAP_UNLOCK(pmap); } m->md.mdpg_cache_attrs = ma; rw_wunlock(&pvh_global_lock); } /* * Map a wired page into kernel virtual address space. */ void moea_kenter(mmu_t mmu, vm_offset_t va, vm_paddr_t pa) { moea_kenter_attr(mmu, va, pa, VM_MEMATTR_DEFAULT); } void moea_kenter_attr(mmu_t mmu, vm_offset_t va, vm_offset_t pa, vm_memattr_t ma) { u_int pte_lo; - int error; + int error; #if 0 if (va < VM_MIN_KERNEL_ADDRESS) panic("moea_kenter: attempt to enter non-kernel address %#x", va); #endif pte_lo = moea_calc_wimg(pa, ma); PMAP_LOCK(kernel_pmap); error = moea_pvo_enter(kernel_pmap, moea_upvo_zone, &moea_pvo_kunmanaged, va, pa, pte_lo, PVO_WIRED); if (error != 0 && error != ENOENT) panic("moea_kenter: failed to enter va %#x pa %#x: %d", va, pa, error); PMAP_UNLOCK(kernel_pmap); } /* * Extract the physical page address associated with the given kernel virtual * address. */ vm_paddr_t moea_kextract(mmu_t mmu, vm_offset_t va) { struct pvo_entry *pvo; vm_paddr_t pa; /* * Allow direct mappings on 32-bit OEA */ if (va < VM_MIN_KERNEL_ADDRESS) { return (va); } PMAP_LOCK(kernel_pmap); pvo = moea_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL); KASSERT(pvo != NULL, ("moea_kextract: no addr found")); pa = (pvo->pvo_pte.pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF); PMAP_UNLOCK(kernel_pmap); return (pa); } /* * Remove a wired page from kernel virtual address space. */ void moea_kremove(mmu_t mmu, vm_offset_t va) { moea_remove(mmu, kernel_pmap, va, va + PAGE_SIZE); } /* * Map a range of physical addresses into kernel virtual address space. * * The value passed in *virt is a suggested virtual address for the mapping. * Architectures which can support a direct-mapped physical to virtual region * can return the appropriate address within that region, leaving '*virt' * unchanged. We cannot and therefore do not; *virt is updated with the * first usable address after the mapped region. */ vm_offset_t moea_map(mmu_t mmu, vm_offset_t *virt, vm_paddr_t pa_start, vm_paddr_t pa_end, int prot) { vm_offset_t sva, va; sva = *virt; va = sva; for (; pa_start < pa_end; pa_start += PAGE_SIZE, va += PAGE_SIZE) moea_kenter(mmu, va, pa_start); *virt = va; return (sva); } /* * Returns true if the pmap's pv is one of the first * 16 pvs linked to from this page. This count may * be changed upwards or downwards in the future; it * is only necessary that true be returned for a small * subset of pmaps for proper page aging. */ boolean_t moea_page_exists_quick(mmu_t mmu, pmap_t pmap, vm_page_t m) { int loops; struct pvo_entry *pvo; boolean_t rv; KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("moea_page_exists_quick: page %p is not managed", m)); loops = 0; rv = FALSE; rw_wlock(&pvh_global_lock); LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) { if (pvo->pvo_pmap == pmap) { rv = TRUE; break; } if (++loops >= 16) break; } rw_wunlock(&pvh_global_lock); return (rv); } /* * Return the number of managed mappings to the given physical page * that are wired. */ int moea_page_wired_mappings(mmu_t mmu, vm_page_t m) { struct pvo_entry *pvo; int count; count = 0; if ((m->oflags & VPO_UNMANAGED) != 0) return (count); rw_wlock(&pvh_global_lock); LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) if ((pvo->pvo_vaddr & PVO_WIRED) != 0) count++; rw_wunlock(&pvh_global_lock); return (count); } static u_int moea_vsidcontext; void moea_pinit(mmu_t mmu, pmap_t pmap) { int i, mask; u_int entropy; KASSERT((int)pmap < VM_MIN_KERNEL_ADDRESS, ("moea_pinit: virt pmap")); RB_INIT(&pmap->pmap_pvo); entropy = 0; __asm __volatile("mftb %0" : "=r"(entropy)); if ((pmap->pmap_phys = (pmap_t)moea_kextract(mmu, (vm_offset_t)pmap)) == NULL) { pmap->pmap_phys = pmap; } - + mtx_lock(&moea_vsid_mutex); /* * Allocate some segment registers for this pmap. */ for (i = 0; i < NPMAPS; i += VSID_NBPW) { u_int hash, n; /* * Create a new value by mutiplying by a prime and adding in * entropy from the timebase register. This is to make the * VSID more random so that the PT hash function collides * less often. (Note that the prime casues gcc to do shifts * instead of a multiply.) */ moea_vsidcontext = (moea_vsidcontext * 0x1105) + entropy; hash = moea_vsidcontext & (NPMAPS - 1); if (hash == 0) /* 0 is special, avoid it */ continue; n = hash >> 5; mask = 1 << (hash & (VSID_NBPW - 1)); hash = (moea_vsidcontext & 0xfffff); if (moea_vsid_bitmap[n] & mask) { /* collision? */ /* anything free in this bucket? */ if (moea_vsid_bitmap[n] == 0xffffffff) { entropy = (moea_vsidcontext >> 20); continue; } i = ffs(~moea_vsid_bitmap[n]) - 1; mask = 1 << i; hash &= 0xfffff & ~(VSID_NBPW - 1); hash |= i; } KASSERT(!(moea_vsid_bitmap[n] & mask), ("Allocating in-use VSID group %#x\n", hash)); moea_vsid_bitmap[n] |= mask; for (i = 0; i < 16; i++) pmap->pm_sr[i] = VSID_MAKE(i, hash); mtx_unlock(&moea_vsid_mutex); return; } mtx_unlock(&moea_vsid_mutex); panic("moea_pinit: out of segments"); } /* * Initialize the pmap associated with process 0. */ void moea_pinit0(mmu_t mmu, pmap_t pm) { PMAP_LOCK_INIT(pm); moea_pinit(mmu, pm); bzero(&pm->pm_stats, sizeof(pm->pm_stats)); } /* * Set the physical protection on the specified range of this map as requested. */ void moea_protect(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) { struct pvo_entry *pvo, *tpvo, key; struct pte *pt; KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap, ("moea_protect: non current pmap")); if ((prot & VM_PROT_READ) == VM_PROT_NONE) { moea_remove(mmu, pm, sva, eva); return; } rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); key.pvo_vaddr = sva; for (pvo = RB_NFIND(pvo_tree, &pm->pmap_pvo, &key); pvo != NULL && PVO_VADDR(pvo) < eva; pvo = tpvo) { tpvo = RB_NEXT(pvo_tree, &pm->pmap_pvo, pvo); /* * Grab the PTE pointer before we diddle with the cached PTE * copy. */ pt = moea_pvo_to_pte(pvo, -1); /* * Change the protection of the page. */ pvo->pvo_pte.pte.pte_lo &= ~PTE_PP; pvo->pvo_pte.pte.pte_lo |= PTE_BR; /* * If the PVO is in the page table, update that pte as well. */ if (pt != NULL) { moea_pte_change(pt, &pvo->pvo_pte.pte, pvo->pvo_vaddr); mtx_unlock(&moea_table_mutex); } } rw_wunlock(&pvh_global_lock); PMAP_UNLOCK(pm); } /* * Map a list of wired pages into kernel virtual address space. This is * intended for temporary mappings which do not need page modification or * references recorded. Existing mappings in the region are overwritten. */ void moea_qenter(mmu_t mmu, vm_offset_t sva, vm_page_t *m, int count) { vm_offset_t va; va = sva; while (count-- > 0) { moea_kenter(mmu, va, VM_PAGE_TO_PHYS(*m)); va += PAGE_SIZE; m++; } } /* * Remove page mappings from kernel virtual address space. Intended for * temporary mappings entered by moea_qenter. */ void moea_qremove(mmu_t mmu, vm_offset_t sva, int count) { vm_offset_t va; va = sva; while (count-- > 0) { moea_kremove(mmu, va); va += PAGE_SIZE; } } void moea_release(mmu_t mmu, pmap_t pmap) { int idx, mask; - + /* * Free segment register's VSID */ if (pmap->pm_sr[0] == 0) panic("moea_release"); mtx_lock(&moea_vsid_mutex); idx = VSID_TO_HASH(pmap->pm_sr[0]) & (NPMAPS-1); mask = 1 << (idx % VSID_NBPW); idx /= VSID_NBPW; moea_vsid_bitmap[idx] &= ~mask; mtx_unlock(&moea_vsid_mutex); } /* * Remove the given range of addresses from the specified map. */ void moea_remove(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva) { struct pvo_entry *pvo, *tpvo, key; rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); key.pvo_vaddr = sva; for (pvo = RB_NFIND(pvo_tree, &pm->pmap_pvo, &key); pvo != NULL && PVO_VADDR(pvo) < eva; pvo = tpvo) { tpvo = RB_NEXT(pvo_tree, &pm->pmap_pvo, pvo); moea_pvo_remove(pvo, -1); } PMAP_UNLOCK(pm); rw_wunlock(&pvh_global_lock); } /* * Remove physical page from all pmaps in which it resides. moea_pvo_remove() * will reflect changes in pte's back to the vm_page. */ void moea_remove_all(mmu_t mmu, vm_page_t m) { struct pvo_head *pvo_head; struct pvo_entry *pvo, *next_pvo; pmap_t pmap; rw_wlock(&pvh_global_lock); pvo_head = vm_page_to_pvoh(m); for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) { next_pvo = LIST_NEXT(pvo, pvo_vlink); pmap = pvo->pvo_pmap; PMAP_LOCK(pmap); moea_pvo_remove(pvo, -1); PMAP_UNLOCK(pmap); } if ((m->aflags & PGA_WRITEABLE) && moea_query_bit(m, PTE_CHG)) { moea_attr_clear(m, PTE_CHG); vm_page_dirty(m); } vm_page_aflag_clear(m, PGA_WRITEABLE); rw_wunlock(&pvh_global_lock); } /* * Allocate a physical page of memory directly from the phys_avail map. * Can only be called from moea_bootstrap before avail start and end are * calculated. */ static vm_offset_t moea_bootstrap_alloc(vm_size_t size, u_int align) { vm_offset_t s, e; int i, j; size = round_page(size); for (i = 0; phys_avail[i + 1] != 0; i += 2) { if (align != 0) s = (phys_avail[i] + align - 1) & ~(align - 1); else s = phys_avail[i]; e = s + size; if (s < phys_avail[i] || e > phys_avail[i + 1]) continue; if (s == phys_avail[i]) { phys_avail[i] += size; } else if (e == phys_avail[i + 1]) { phys_avail[i + 1] -= size; } else { for (j = phys_avail_count * 2; j > i; j -= 2) { phys_avail[j] = phys_avail[j - 2]; phys_avail[j + 1] = phys_avail[j - 1]; } phys_avail[i + 3] = phys_avail[i + 1]; phys_avail[i + 1] = s; phys_avail[i + 2] = e; phys_avail_count++; } return (s); } panic("moea_bootstrap_alloc: could not allocate memory"); } static void moea_syncicache(vm_offset_t pa, vm_size_t len) { __syncicache((void *)pa, len); } static int moea_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head, vm_offset_t va, vm_offset_t pa, u_int pte_lo, int flags) { struct pvo_entry *pvo; u_int sr; int first; u_int ptegidx; int i; int bootstrap; moea_pvo_enter_calls++; first = 0; bootstrap = 0; /* * Compute the PTE Group index. */ va &= ~ADDR_POFF; sr = va_to_sr(pm->pm_sr, va); ptegidx = va_to_pteg(sr, va); /* * Remove any existing mapping for this page. Reuse the pvo entry if * there is a mapping. */ mtx_lock(&moea_table_mutex); LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) { if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) { if ((pvo->pvo_pte.pte.pte_lo & PTE_RPGN) == pa && (pvo->pvo_pte.pte.pte_lo & PTE_PP) == (pte_lo & PTE_PP)) { /* * The PTE is not changing. Instead, this may * be a request to change the mapping's wired * attribute. */ mtx_unlock(&moea_table_mutex); if ((flags & PVO_WIRED) != 0 && (pvo->pvo_vaddr & PVO_WIRED) == 0) { pvo->pvo_vaddr |= PVO_WIRED; pm->pm_stats.wired_count++; } else if ((flags & PVO_WIRED) == 0 && (pvo->pvo_vaddr & PVO_WIRED) != 0) { pvo->pvo_vaddr &= ~PVO_WIRED; pm->pm_stats.wired_count--; } return (0); } moea_pvo_remove(pvo, -1); break; } } /* * If we aren't overwriting a mapping, try to allocate. */ if (moea_initialized) { pvo = uma_zalloc(zone, M_NOWAIT); } else { if (moea_bpvo_pool_index >= BPVO_POOL_SIZE) { panic("moea_enter: bpvo pool exhausted, %d, %d, %d", - moea_bpvo_pool_index, BPVO_POOL_SIZE, + moea_bpvo_pool_index, BPVO_POOL_SIZE, BPVO_POOL_SIZE * sizeof(struct pvo_entry)); } pvo = &moea_bpvo_pool[moea_bpvo_pool_index]; moea_bpvo_pool_index++; bootstrap = 1; } if (pvo == NULL) { mtx_unlock(&moea_table_mutex); return (ENOMEM); } moea_pvo_entries++; pvo->pvo_vaddr = va; pvo->pvo_pmap = pm; LIST_INSERT_HEAD(&moea_pvo_table[ptegidx], pvo, pvo_olink); pvo->pvo_vaddr &= ~ADDR_POFF; if (flags & PVO_WIRED) pvo->pvo_vaddr |= PVO_WIRED; if (pvo_head != &moea_pvo_kunmanaged) pvo->pvo_vaddr |= PVO_MANAGED; if (bootstrap) pvo->pvo_vaddr |= PVO_BOOTSTRAP; moea_pte_create(&pvo->pvo_pte.pte, sr, va, pa | pte_lo); /* * Add to pmap list */ RB_INSERT(pvo_tree, &pm->pmap_pvo, pvo); /* * Remember if the list was empty and therefore will be the first * item. */ if (LIST_FIRST(pvo_head) == NULL) first = 1; LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink); if (pvo->pvo_vaddr & PVO_WIRED) pm->pm_stats.wired_count++; pm->pm_stats.resident_count++; i = moea_pte_insert(ptegidx, &pvo->pvo_pte.pte); KASSERT(i < 8, ("Invalid PTE index")); if (i >= 0) { PVO_PTEGIDX_SET(pvo, i); } else { panic("moea_pvo_enter: overflow"); moea_pte_overflow++; } mtx_unlock(&moea_table_mutex); return (first ? ENOENT : 0); } static void moea_pvo_remove(struct pvo_entry *pvo, int pteidx) { struct pte *pt; /* * If there is an active pte entry, we need to deactivate it (and * save the ref & cfg bits). */ pt = moea_pvo_to_pte(pvo, pteidx); if (pt != NULL) { moea_pte_unset(pt, &pvo->pvo_pte.pte, pvo->pvo_vaddr); mtx_unlock(&moea_table_mutex); PVO_PTEGIDX_CLR(pvo); } else { moea_pte_overflow--; } /* * Update our statistics. */ pvo->pvo_pmap->pm_stats.resident_count--; if (pvo->pvo_vaddr & PVO_WIRED) pvo->pvo_pmap->pm_stats.wired_count--; /* * Save the REF/CHG bits into their cache if the page is managed. */ if ((pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED) { struct vm_page *pg; pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte.pte_lo & PTE_RPGN); if (pg != NULL) { moea_attr_save(pg, pvo->pvo_pte.pte.pte_lo & (PTE_REF | PTE_CHG)); } } /* * Remove this PVO from the PV and pmap lists. */ LIST_REMOVE(pvo, pvo_vlink); RB_REMOVE(pvo_tree, &pvo->pvo_pmap->pmap_pvo, pvo); /* * Remove this from the overflow list and return it to the pool * if we aren't going to reuse it. */ LIST_REMOVE(pvo, pvo_olink); if (!(pvo->pvo_vaddr & PVO_BOOTSTRAP)) uma_zfree(pvo->pvo_vaddr & PVO_MANAGED ? moea_mpvo_zone : moea_upvo_zone, pvo); moea_pvo_entries--; moea_pvo_remove_calls++; } static __inline int moea_pvo_pte_index(const struct pvo_entry *pvo, int ptegidx) { int pteidx; /* * We can find the actual pte entry without searching by grabbing * the PTEG index from 3 unused bits in pte_lo[11:9] and by * noticing the HID bit. */ pteidx = ptegidx * 8 + PVO_PTEGIDX_GET(pvo); if (pvo->pvo_pte.pte.pte_hi & PTE_HID) pteidx ^= moea_pteg_mask * 8; return (pteidx); } static struct pvo_entry * moea_pvo_find_va(pmap_t pm, vm_offset_t va, int *pteidx_p) { struct pvo_entry *pvo; int ptegidx; u_int sr; va &= ~ADDR_POFF; sr = va_to_sr(pm->pm_sr, va); ptegidx = va_to_pteg(sr, va); mtx_lock(&moea_table_mutex); LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) { if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) { if (pteidx_p) *pteidx_p = moea_pvo_pte_index(pvo, ptegidx); break; } } mtx_unlock(&moea_table_mutex); return (pvo); } static struct pte * moea_pvo_to_pte(const struct pvo_entry *pvo, int pteidx) { struct pte *pt; /* * If we haven't been supplied the ptegidx, calculate it. */ if (pteidx == -1) { int ptegidx; u_int sr; sr = va_to_sr(pvo->pvo_pmap->pm_sr, pvo->pvo_vaddr); ptegidx = va_to_pteg(sr, pvo->pvo_vaddr); pteidx = moea_pvo_pte_index(pvo, ptegidx); } pt = &moea_pteg_table[pteidx >> 3].pt[pteidx & 7]; mtx_lock(&moea_table_mutex); if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) { panic("moea_pvo_to_pte: pvo %p has valid pte in pvo but no " "valid pte index", pvo); } if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0 && PVO_PTEGIDX_ISSET(pvo)) { panic("moea_pvo_to_pte: pvo %p has valid pte index in pvo " "pvo but no valid pte", pvo); } if ((pt->pte_hi ^ (pvo->pvo_pte.pte.pte_hi & ~PTE_VALID)) == PTE_VALID) { if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0) { panic("moea_pvo_to_pte: pvo %p has valid pte in " "moea_pteg_table %p but invalid in pvo", pvo, pt); } if (((pt->pte_lo ^ pvo->pvo_pte.pte.pte_lo) & ~(PTE_CHG|PTE_REF)) != 0) { panic("moea_pvo_to_pte: pvo %p pte does not match " "pte %p in moea_pteg_table", pvo, pt); } mtx_assert(&moea_table_mutex, MA_OWNED); return (pt); } if (pvo->pvo_pte.pte.pte_hi & PTE_VALID) { panic("moea_pvo_to_pte: pvo %p has invalid pte %p in " "moea_pteg_table but valid in pvo: %8x, %8x", pvo, pt, pvo->pvo_pte.pte.pte_hi, pt->pte_hi); } mtx_unlock(&moea_table_mutex); return (NULL); } /* * XXX: THIS STUFF SHOULD BE IN pte.c? */ int moea_pte_spill(vm_offset_t addr) { struct pvo_entry *source_pvo, *victim_pvo; struct pvo_entry *pvo; int ptegidx, i, j; u_int sr; struct pteg *pteg; struct pte *pt; moea_pte_spills++; sr = mfsrin(addr); ptegidx = va_to_pteg(sr, addr); /* * Have to substitute some entry. Use the primary hash for this. * Use low bits of timebase as random generator. */ pteg = &moea_pteg_table[ptegidx]; mtx_lock(&moea_table_mutex); __asm __volatile("mftb %0" : "=r"(i)); i &= 7; pt = &pteg->pt[i]; source_pvo = NULL; victim_pvo = NULL; LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) { /* * We need to find a pvo entry for this address. */ if (source_pvo == NULL && moea_pte_match(&pvo->pvo_pte.pte, sr, addr, pvo->pvo_pte.pte.pte_hi & PTE_HID)) { /* * Now found an entry to be spilled into the pteg. * The PTE is now valid, so we know it's active. */ j = moea_pte_insert(ptegidx, &pvo->pvo_pte.pte); if (j >= 0) { PVO_PTEGIDX_SET(pvo, j); moea_pte_overflow--; mtx_unlock(&moea_table_mutex); return (1); } source_pvo = pvo; if (victim_pvo != NULL) break; } /* * We also need the pvo entry of the victim we are replacing * so save the R & C bits of the PTE. */ if ((pt->pte_hi & PTE_HID) == 0 && victim_pvo == NULL && moea_pte_compare(pt, &pvo->pvo_pte.pte)) { victim_pvo = pvo; if (source_pvo != NULL) break; } } if (source_pvo == NULL) { mtx_unlock(&moea_table_mutex); return (0); } if (victim_pvo == NULL) { if ((pt->pte_hi & PTE_HID) == 0) panic("moea_pte_spill: victim p-pte (%p) has no pvo" "entry", pt); /* * If this is a secondary PTE, we need to search it's primary * pvo bucket for the matching PVO. */ LIST_FOREACH(pvo, &moea_pvo_table[ptegidx ^ moea_pteg_mask], pvo_olink) { /* * We also need the pvo entry of the victim we are * replacing so save the R & C bits of the PTE. */ if (moea_pte_compare(pt, &pvo->pvo_pte.pte)) { victim_pvo = pvo; break; } } if (victim_pvo == NULL) panic("moea_pte_spill: victim s-pte (%p) has no pvo" "entry", pt); } /* * We are invalidating the TLB entry for the EA we are replacing even * though it's valid. If we don't, we lose any ref/chg bit changes * contained in the TLB entry. */ source_pvo->pvo_pte.pte.pte_hi &= ~PTE_HID; moea_pte_unset(pt, &victim_pvo->pvo_pte.pte, victim_pvo->pvo_vaddr); moea_pte_set(pt, &source_pvo->pvo_pte.pte); PVO_PTEGIDX_CLR(victim_pvo); PVO_PTEGIDX_SET(source_pvo, i); moea_pte_replacements++; mtx_unlock(&moea_table_mutex); return (1); } static __inline struct pvo_entry * moea_pte_spillable_ident(u_int ptegidx) { struct pte *pt; struct pvo_entry *pvo_walk, *pvo = NULL; LIST_FOREACH(pvo_walk, &moea_pvo_table[ptegidx], pvo_olink) { if (pvo_walk->pvo_vaddr & PVO_WIRED) continue; if (!(pvo_walk->pvo_pte.pte.pte_hi & PTE_VALID)) continue; pt = moea_pvo_to_pte(pvo_walk, -1); if (pt == NULL) continue; pvo = pvo_walk; mtx_unlock(&moea_table_mutex); if (!(pt->pte_lo & PTE_REF)) return (pvo_walk); } - + return (pvo); } static int moea_pte_insert(u_int ptegidx, struct pte *pvo_pt) { struct pte *pt; struct pvo_entry *victim_pvo; int i; int victim_idx; u_int pteg_bkpidx = ptegidx; mtx_assert(&moea_table_mutex, MA_OWNED); /* * First try primary hash. */ for (pt = moea_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) { if ((pt->pte_hi & PTE_VALID) == 0) { pvo_pt->pte_hi &= ~PTE_HID; moea_pte_set(pt, pvo_pt); return (i); } } /* * Now try secondary hash. */ ptegidx ^= moea_pteg_mask; for (pt = moea_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) { if ((pt->pte_hi & PTE_VALID) == 0) { pvo_pt->pte_hi |= PTE_HID; moea_pte_set(pt, pvo_pt); return (i); } } /* Try again, but this time try to force a PTE out. */ ptegidx = pteg_bkpidx; victim_pvo = moea_pte_spillable_ident(ptegidx); if (victim_pvo == NULL) { ptegidx ^= moea_pteg_mask; victim_pvo = moea_pte_spillable_ident(ptegidx); } if (victim_pvo == NULL) { panic("moea_pte_insert: overflow"); return (-1); } victim_idx = moea_pvo_pte_index(victim_pvo, ptegidx); if (pteg_bkpidx == ptegidx) pvo_pt->pte_hi &= ~PTE_HID; else pvo_pt->pte_hi |= PTE_HID; /* * Synchronize the sacrifice PTE with its PVO, then mark both * invalid. The PVO will be reused when/if the VM system comes * here after a fault. */ pt = &moea_pteg_table[victim_idx >> 3].pt[victim_idx & 7]; if (pt->pte_hi != victim_pvo->pvo_pte.pte.pte_hi) panic("Victim PVO doesn't match PTE! PVO: %8x, PTE: %8x", victim_pvo->pvo_pte.pte.pte_hi, pt->pte_hi); /* * Set the new PTE. */ moea_pte_unset(pt, &victim_pvo->pvo_pte.pte, victim_pvo->pvo_vaddr); PVO_PTEGIDX_CLR(victim_pvo); moea_pte_overflow++; moea_pte_set(pt, pvo_pt); return (victim_idx & 7); } static boolean_t moea_query_bit(vm_page_t m, int ptebit) { struct pvo_entry *pvo; struct pte *pt; rw_assert(&pvh_global_lock, RA_WLOCKED); if (moea_attr_fetch(m) & ptebit) return (TRUE); LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) { /* * See if we saved the bit off. If so, cache it and return * success. */ if (pvo->pvo_pte.pte.pte_lo & ptebit) { moea_attr_save(m, ptebit); return (TRUE); } } /* * No luck, now go through the hard part of looking at the PTEs * themselves. Sync so that any pending REF/CHG bits are flushed to * the PTEs. */ powerpc_sync(); LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) { /* * See if this pvo has a valid PTE. if so, fetch the * REF/CHG bits from the valid PTE. If the appropriate * ptebit is set, cache it and return success. */ pt = moea_pvo_to_pte(pvo, -1); if (pt != NULL) { moea_pte_synch(pt, &pvo->pvo_pte.pte); mtx_unlock(&moea_table_mutex); if (pvo->pvo_pte.pte.pte_lo & ptebit) { moea_attr_save(m, ptebit); return (TRUE); } } } return (FALSE); } static u_int moea_clear_bit(vm_page_t m, int ptebit) { u_int count; struct pvo_entry *pvo; struct pte *pt; rw_assert(&pvh_global_lock, RA_WLOCKED); /* * Clear the cached value. */ moea_attr_clear(m, ptebit); /* * Sync so that any pending REF/CHG bits are flushed to the PTEs (so * we can reset the right ones). note that since the pvo entries and * list heads are accessed via BAT0 and are never placed in the page * table, we don't have to worry about further accesses setting the * REF/CHG bits. */ powerpc_sync(); /* * For each pvo entry, clear the pvo's ptebit. If this pvo has a * valid pte clear the ptebit from the valid pte. */ count = 0; LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) { pt = moea_pvo_to_pte(pvo, -1); if (pt != NULL) { moea_pte_synch(pt, &pvo->pvo_pte.pte); if (pvo->pvo_pte.pte.pte_lo & ptebit) { count++; moea_pte_clear(pt, PVO_VADDR(pvo), ptebit); } mtx_unlock(&moea_table_mutex); } pvo->pvo_pte.pte.pte_lo &= ~ptebit; } return (count); } /* * Return true if the physical range is encompassed by the battable[idx] */ static int moea_bat_mapped(int idx, vm_offset_t pa, vm_size_t size) { u_int prot; u_int32_t start; u_int32_t end; u_int32_t bat_ble; /* * Return immediately if not a valid mapping */ if (!(battable[idx].batu & BAT_Vs)) return (EINVAL); /* * The BAT entry must be cache-inhibited, guarded, and r/w * so it can function as an i/o page */ prot = battable[idx].batl & (BAT_I|BAT_G|BAT_PP_RW); if (prot != (BAT_I|BAT_G|BAT_PP_RW)) - return (EPERM); + return (EPERM); /* * The address should be within the BAT range. Assume that the * start address in the BAT has the correct alignment (thus * not requiring masking) */ start = battable[idx].batl & BAT_PBS; bat_ble = (battable[idx].batu & ~(BAT_EBS)) | 0x03; end = start | (bat_ble << 15) | 0x7fff; if ((pa < start) || ((pa + size) > end)) return (ERANGE); return (0); } boolean_t moea_dev_direct_mapped(mmu_t mmu, vm_paddr_t pa, vm_size_t size) { int i; /* - * This currently does not work for entries that + * This currently does not work for entries that * overlap 256M BAT segments. */ for(i = 0; i < 16; i++) if (moea_bat_mapped(i, pa, size) == 0) return (0); return (EFAULT); } /* * Map a set of physical memory pages into the kernel virtual * address space. Return a pointer to where it is mapped. This * routine is intended to be used for mapping device memory, * NOT real memory. */ void * moea_mapdev(mmu_t mmu, vm_paddr_t pa, vm_size_t size) { return (moea_mapdev_attr(mmu, pa, size, VM_MEMATTR_DEFAULT)); } void * moea_mapdev_attr(mmu_t mmu, vm_offset_t pa, vm_size_t size, vm_memattr_t ma) { vm_offset_t va, tmpva, ppa, offset; int i; ppa = trunc_page(pa); offset = pa & PAGE_MASK; size = roundup(offset + size, PAGE_SIZE); - + /* * If the physical address lies within a valid BAT table entry, * return the 1:1 mapping. This currently doesn't work * for regions that overlap 256M BAT segments. */ for (i = 0; i < 16; i++) { if (moea_bat_mapped(i, pa, size) == 0) return ((void *) pa); } va = kva_alloc(size); if (!va) panic("moea_mapdev: Couldn't alloc kernel virtual memory"); for (tmpva = va; size > 0;) { moea_kenter_attr(mmu, tmpva, ppa, ma); tlbie(tmpva); size -= PAGE_SIZE; tmpva += PAGE_SIZE; ppa += PAGE_SIZE; } return ((void *)(va + offset)); } void moea_unmapdev(mmu_t mmu, vm_offset_t va, vm_size_t size) { vm_offset_t base, offset; /* * If this is outside kernel virtual space, then it's a * battable entry and doesn't require unmapping */ if ((va >= VM_MIN_KERNEL_ADDRESS) && (va <= virtual_end)) { base = trunc_page(va); offset = va & PAGE_MASK; size = roundup(offset + size, PAGE_SIZE); kva_free(base, size); } } static void moea_sync_icache(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_size_t sz) { struct pvo_entry *pvo; vm_offset_t lim; vm_paddr_t pa; vm_size_t len; PMAP_LOCK(pm); while (sz > 0) { lim = round_page(va); len = MIN(lim - va, sz); pvo = moea_pvo_find_va(pm, va & ~ADDR_POFF, NULL); if (pvo != NULL) { pa = (pvo->pvo_pte.pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF); moea_syncicache(pa, len); } va += len; sz -= len; } PMAP_UNLOCK(pm); } void moea_dumpsys_map(mmu_t mmu, vm_paddr_t pa, size_t sz, void **va) { *va = (void *)pa; } extern struct dump_pa dump_map[PHYS_AVAIL_SZ + 1]; void moea_scan_init(mmu_t mmu) { struct pvo_entry *pvo; vm_offset_t va; int i; if (!do_minidump) { /* Initialize phys. segments for dumpsys(). */ memset(&dump_map, 0, sizeof(dump_map)); mem_regions(&pregions, &pregions_sz, ®ions, ®ions_sz); for (i = 0; i < pregions_sz; i++) { dump_map[i].pa_start = pregions[i].mr_start; dump_map[i].pa_size = pregions[i].mr_size; } return; } /* Virtual segments for minidumps: */ memset(&dump_map, 0, sizeof(dump_map)); /* 1st: kernel .data and .bss. */ dump_map[0].pa_start = trunc_page((uintptr_t)_etext); dump_map[0].pa_size = round_page((uintptr_t)_end) - dump_map[0].pa_start; /* 2nd: msgbuf and tables (see pmap_bootstrap()). */ dump_map[1].pa_start = (vm_paddr_t)msgbufp->msg_ptr; dump_map[1].pa_size = round_page(msgbufp->msg_size); /* 3rd: kernel VM. */ va = dump_map[1].pa_start + dump_map[1].pa_size; /* Find start of next chunk (from va). */ while (va < virtual_end) { /* Don't dump the buffer cache. */ if (va >= kmi.buffer_sva && va < kmi.buffer_eva) { va = kmi.buffer_eva; continue; } pvo = moea_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL); if (pvo != NULL && (pvo->pvo_pte.pte.pte_hi & PTE_VALID)) break; va += PAGE_SIZE; } if (va < virtual_end) { dump_map[2].pa_start = va; va += PAGE_SIZE; /* Find last page in chunk. */ while (va < virtual_end) { /* Don't run into the buffer cache. */ if (va == kmi.buffer_sva) break; pvo = moea_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL); if (pvo == NULL || !(pvo->pvo_pte.pte.pte_hi & PTE_VALID)) break; va += PAGE_SIZE; } dump_map[2].pa_size = va - dump_map[2].pa_start; } } Index: head/sys/powerpc/conf/WII =================================================================== --- head/sys/powerpc/conf/WII (revision 278494) +++ head/sys/powerpc/conf/WII (nonexistent) @@ -1,110 +0,0 @@ -# -# Custom kernel for the Nintendo Wii. -# -# $FreeBSD$ - -cpu AIM -ident WII -machine powerpc powerpc - -makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols - -options WII - -options SCHED_ULE #ULE scheduler -options PREEMPTION #Enable kernel thread preemption -options INET #InterNETworking -options INET6 #IPv6 communications protocols -options SCTP #Stream Control Transmission Protocol -options FFS #Berkeley Fast Filesystem -options SOFTUPDATES #Enable FFS soft updates support -options UFS_ACL #Support for access control lists -options UFS_DIRHASH #Improve performance on big directories -options UFS_GJOURNAL #Enable gjournal-based UFS journaling -options MD_ROOT #MD is a potential root device -options NFSCL #Network Filesystem Client -options NFSD #Network Filesystem Server -options NFSLOCKD #Network Lock Manager -options NFS_ROOT #NFS usable as root device -options MSDOSFS #MSDOS Filesystem -options CD9660 #ISO 9660 Filesystem -options PROCFS #Process filesystem (requires PSEUDOFS) -options PSEUDOFS #Pseudo-filesystem framework -options GEOM_PART_GPT #GUID Partition Tables. -options GEOM_LABEL #Provides labelization -options SCSI_DELAY=5000 #Delay (in ms) before probing SCSI -options KTRACE #ktrace(1) syscall trace support -options STACK #stack(9) support -options SYSVSHM #SYSV-style shared memory -options SYSVMSG #SYSV-style message queues -options SYSVSEM #SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions -#options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) -options AUDIT # Security event auditing -options CAPABILITY_MODE # Capsicum capability mode -options CAPABILITIES # Capsicum capabilities -options MAC # TrustedBSD MAC Framework -options INCLUDE_CONFIG_FILE # Include this file in kernel - -# Debugging support. Always need this: -options KDB # Enable kernel debugger support. -# For minimum debugger support (stable branch) use: -options KDB_TRACE # Print a stack trace for a panic. -# For full debugger support use this instead: -options DDB #Support DDB -#options DEADLKRES #Enable the deadlock resolver -options INVARIANTS #Enable calls of extra sanity checking -options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS -options WITNESS #Enable checks to detect deadlocks and cycles -options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed -options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones - -# ATA/SCSI peripherals -device scbus # SCSI bus (required for ATA/SCSI) -device da # Direct Access (disks) - -# syscons is the default console driver, resembling an SCO console -device sc -device kbdmux -options SC_DFLT_FONT # compile font in -makeoptions SC_DFLT_FONT=cp437 - -# Pseudo devices. -device loop # Network loopback -device random # Entropy device -device ether # Ethernet support -device vlan # 802.1Q VLAN support -device tun # Packet tunnel. -device md # Memory "disks" -device gif # IPv6 and IPv4 tunneling -device firmware # firmware assist module - - -# The `bpf' device enables the Berkeley Packet Filter. -# Be aware of the administrative consequences of enabling this! -# Note that 'bpf' is required for DHCP. -device bpf #Berkeley packet filter - -# USB support -options USB_DEBUG # enable debug msgs -device uhci # UHCI PCI->USB interface -device ohci # OHCI PCI->USB interface -device ehci # EHCI PCI->USB interface -device usb # USB Bus (required) -device uhid # "Human Interface Devices" -device ukbd # Keyboard -options KBD_INSTALL_CDEV # install a CDEV entry in /dev -device ulpt # Printer -device umass # Disks/Mass storage - Requires scbus and da0 -device ums # Mouse -# USB Ethernet -device miibus # MII bus support -device aue # ADMtek USB Ethernet -device axe # ASIX Electronics USB Ethernet -device cdce # Generic USB over Ethernet -device cue # CATC USB Ethernet -device kue # Kawasaki LSI USB Ethernet - -# GPIO -device gpio -device wiigpio Property changes on: head/sys/powerpc/conf/WII ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/powerpc/conf/NOTES =================================================================== --- head/sys/powerpc/conf/NOTES (revision 278494) +++ head/sys/powerpc/conf/NOTES (revision 278495) @@ -1,95 +1,94 @@ # $FreeBSD$ # # This file contains machine dependent kernel configuration notes. For # machine independent notes, look in /sys/conf/NOTES. ##################################################################### # CPU OPTIONS # You must specify a machine directive to choose powerpc or powerpc64 #machine powerpc powerpc[64] # # You must specify at least one CPU (the one you intend to run on). cpu AIM #cpu BOOKE_E500 #cpu BOOKE_PPC440 options FPU_EMU #options MPC85XX options POWERMAC #NewWorld Apple PowerMacs #options PS3 #Sony Playstation 3 options PSIM #GDB PSIM ppc simulator options MAMBO #IBM Mambo Full System Simulator -#options WII #Nintendo Wii options SC_OFWFB # OFW frame buffer # The cpufreq(4) driver provides support for CPU frequency control device cpufreq # Standard busses device pci device agp device bm # Apple BMAC (Big Mac Ethernet) device glc # Sony Playstation 3 Ethernet device kiic # Apple Keywest I2C Controller device ofwd # Open Firmware disks device adb # Apple Desktop Bus device cuda # VIA-CUDA ADB interface device ad7417 # PowerMac7,2 temperature sensor device ds1631 # PowerMac11,2 temperature sensor device ds1775 # PowerMac7,2 temperature sensor device fcu # Apple Fan Control Unit device max6690 # PowerMac7,2 temperature sensor device pmu # Apple Power Management Unit device smu # Apple System Management Unit device snd_ai2s # Apple I2S Audio device snd_davbus # Apple Davbus Audio device adm1030 # Apple G4 MDD fan controller ##################################################################### # Devices we don't want to deal with nodevice bktr nodevice cxgbe # XXX: builds on powerpc64 only. nodevice fdc nodevice ppc nodevice splash # when splash works enable *_saver nodevice blank_saver nodevice daemon_saver nodevice dragon_saver nodevice fade_saver nodevice fire_saver nodevice green_saver nodevice logo_saver nodevice rain_saver nodevice snake_saver nodevice star_saver nodevice warp_saver nodevice daemon_saver nodevice star_saver nodevice snake_saver # isa nodevice pcii nodevice tnt4882 # sound nodevice snd_cmi # wants gdb_cur nodevice dcons nodevice dcons_crom ##################################################################### # Options we don't want to deal with nooption PPC_DEBUG nooption PPC_PROBE_CHIPSET nooption SC_NO_MODE_CHANGE nooption UKBD_DFLT_KEYMAP Index: head/sys/powerpc/ofw/ofw_syscons.c =================================================================== --- head/sys/powerpc/ofw/ofw_syscons.c (revision 278494) +++ head/sys/powerpc/ofw/ofw_syscons.c (revision 278495) @@ -1,1108 +1,1102 @@ /*- * Copyright (c) 2003 Peter Grehan * 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 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 AUTHOR 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int ofwfb_ignore_mmap_checks = 1; static int ofwfb_reset_on_switch = 1; static SYSCTL_NODE(_hw, OID_AUTO, ofwfb, CTLFLAG_RD, 0, "ofwfb"); SYSCTL_INT(_hw_ofwfb, OID_AUTO, relax_mmap, CTLFLAG_RW, &ofwfb_ignore_mmap_checks, 0, "relaxed mmap bounds checking"); SYSCTL_INT(_hw_ofwfb, OID_AUTO, reset_on_mode_switch, CTLFLAG_RW, &ofwfb_reset_on_switch, 0, "reset the framebuffer driver on mode switch"); extern u_char dflt_font_16[]; extern u_char dflt_font_14[]; extern u_char dflt_font_8[]; static int ofwfb_configure(int flags); static vi_probe_t ofwfb_probe; static vi_init_t ofwfb_init; static vi_get_info_t ofwfb_get_info; static vi_query_mode_t ofwfb_query_mode; static vi_set_mode_t ofwfb_set_mode; static vi_save_font_t ofwfb_save_font; static vi_load_font_t ofwfb_load_font; static vi_show_font_t ofwfb_show_font; static vi_save_palette_t ofwfb_save_palette; static vi_load_palette_t ofwfb_load_palette; static vi_set_border_t ofwfb_set_border; static vi_save_state_t ofwfb_save_state; static vi_load_state_t ofwfb_load_state; static vi_set_win_org_t ofwfb_set_win_org; static vi_read_hw_cursor_t ofwfb_read_hw_cursor; static vi_set_hw_cursor_t ofwfb_set_hw_cursor; static vi_set_hw_cursor_shape_t ofwfb_set_hw_cursor_shape; static vi_blank_display_t ofwfb_blank_display; static vi_mmap_t ofwfb_mmap; static vi_ioctl_t ofwfb_ioctl; static vi_clear_t ofwfb_clear; static vi_fill_rect_t ofwfb_fill_rect; static vi_bitblt_t ofwfb_bitblt; static vi_diag_t ofwfb_diag; static vi_save_cursor_palette_t ofwfb_save_cursor_palette; static vi_load_cursor_palette_t ofwfb_load_cursor_palette; static vi_copy_t ofwfb_copy; static vi_putp_t ofwfb_putp; static vi_putc_t ofwfb_putc; static vi_puts_t ofwfb_puts; static vi_putm_t ofwfb_putm; static video_switch_t ofwfbvidsw = { .probe = ofwfb_probe, .init = ofwfb_init, .get_info = ofwfb_get_info, .query_mode = ofwfb_query_mode, .set_mode = ofwfb_set_mode, .save_font = ofwfb_save_font, .load_font = ofwfb_load_font, .show_font = ofwfb_show_font, .save_palette = ofwfb_save_palette, .load_palette = ofwfb_load_palette, .set_border = ofwfb_set_border, .save_state = ofwfb_save_state, .load_state = ofwfb_load_state, .set_win_org = ofwfb_set_win_org, .read_hw_cursor = ofwfb_read_hw_cursor, .set_hw_cursor = ofwfb_set_hw_cursor, .set_hw_cursor_shape = ofwfb_set_hw_cursor_shape, .blank_display = ofwfb_blank_display, .mmap = ofwfb_mmap, .ioctl = ofwfb_ioctl, .clear = ofwfb_clear, .fill_rect = ofwfb_fill_rect, .bitblt = ofwfb_bitblt, .diag = ofwfb_diag, .save_cursor_palette = ofwfb_save_cursor_palette, .load_cursor_palette = ofwfb_load_cursor_palette, .copy = ofwfb_copy, .putp = ofwfb_putp, .putc = ofwfb_putc, .puts = ofwfb_puts, .putm = ofwfb_putm, }; /* * bitmap depth-specific routines */ static vi_blank_display_t ofwfb_blank_display8; static vi_putc_t ofwfb_putc8; static vi_putm_t ofwfb_putm8; static vi_set_border_t ofwfb_set_border8; static vi_blank_display_t ofwfb_blank_display32; static vi_putc_t ofwfb_putc32; static vi_putm_t ofwfb_putm32; static vi_set_border_t ofwfb_set_border32; VIDEO_DRIVER(ofwfb, ofwfbvidsw, ofwfb_configure); extern sc_rndr_sw_t txtrndrsw; RENDERER(ofwfb, 0, txtrndrsw, gfb_set); RENDERER_MODULE(ofwfb, gfb_set); /* * Define the iso6429-1983 colormap */ static struct { uint8_t red; uint8_t green; uint8_t blue; } ofwfb_cmap[16] = { /* # R G B Color */ /* - - - - ----- */ { 0x00, 0x00, 0x00 }, /* 0 0 0 0 Black */ { 0x00, 0x00, 0xaa }, /* 1 0 0 2/3 Blue */ { 0x00, 0xaa, 0x00 }, /* 2 0 2/3 0 Green */ { 0x00, 0xaa, 0xaa }, /* 3 0 2/3 2/3 Cyan */ { 0xaa, 0x00, 0x00 }, /* 4 2/3 0 0 Red */ { 0xaa, 0x00, 0xaa }, /* 5 2/3 0 2/3 Magenta */ { 0xaa, 0x55, 0x00 }, /* 6 2/3 1/3 0 Brown */ { 0xaa, 0xaa, 0xaa }, /* 7 2/3 2/3 2/3 White */ { 0x55, 0x55, 0x55 }, /* 8 1/3 1/3 1/3 Gray */ { 0x55, 0x55, 0xff }, /* 9 1/3 1/3 1 Bright Blue */ { 0x55, 0xff, 0x55 }, /* 10 1/3 1 1/3 Bright Green */ { 0x55, 0xff, 0xff }, /* 11 1/3 1 1 Bright Cyan */ { 0xff, 0x55, 0x55 }, /* 12 1 1/3 1/3 Bright Red */ { 0xff, 0x55, 0xff }, /* 13 1 1/3 1 Bright Magenta */ { 0xff, 0xff, 0x80 }, /* 14 1 1 1/3 Bright Yellow */ { 0xff, 0xff, 0xff } /* 15 1 1 1 Bright White */ }; #define TODO printf("%s: unimplemented\n", __func__) static u_int16_t ofwfb_static_window[ROW*COL]; static struct ofwfb_softc ofwfb_softc; static __inline int ofwfb_background(uint8_t attr) { return (attr >> 4); } static __inline int ofwfb_foreground(uint8_t attr) { return (attr & 0x0f); } static u_int ofwfb_pix32(struct ofwfb_softc *sc, int attr) { u_int retval; if (sc->sc_tag == &bs_le_tag) retval = (ofwfb_cmap[attr].red << 16) | (ofwfb_cmap[attr].green << 8) | ofwfb_cmap[attr].blue; else retval = (ofwfb_cmap[attr].blue << 16) | (ofwfb_cmap[attr].green << 8) | ofwfb_cmap[attr].red; return (retval); } static int ofwfb_configure(int flags) { struct ofwfb_softc *sc; phandle_t chosen; ihandle_t stdout; phandle_t node; uint32_t fb_phys; int depth; int disable; int len; int i; char type[16]; static int done = 0; disable = 0; TUNABLE_INT_FETCH("hw.syscons.disable", &disable); if (disable != 0) return (0); if (done != 0) return (0); done = 1; sc = &ofwfb_softc; chosen = OF_finddevice("/chosen"); OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); node = OF_instance_to_package(stdout); if (node == -1) { /* * The "/chosen/stdout" does not exist try * using "screen" directly. */ node = OF_finddevice("screen"); } OF_getprop(node, "device_type", type, sizeof(type)); if (strcmp(type, "display") != 0) return (0); /* Only support 8 and 32-bit framebuffers */ OF_getprop(node, "depth", &depth, sizeof(depth)); if (depth == 8) { sc->sc_blank = ofwfb_blank_display8; sc->sc_putc = ofwfb_putc8; sc->sc_putm = ofwfb_putm8; sc->sc_set_border = ofwfb_set_border8; } else if (depth == 32) { sc->sc_blank = ofwfb_blank_display32; sc->sc_putc = ofwfb_putc32; sc->sc_putm = ofwfb_putm32; sc->sc_set_border = ofwfb_set_border32; } else return (0); if (OF_getproplen(node, "height") != sizeof(sc->sc_height) || OF_getproplen(node, "width") != sizeof(sc->sc_width) || OF_getproplen(node, "linebytes") != sizeof(sc->sc_stride)) return (0); sc->sc_depth = depth; sc->sc_node = node; sc->sc_console = 1; OF_getprop(node, "height", &sc->sc_height, sizeof(sc->sc_height)); OF_getprop(node, "width", &sc->sc_width, sizeof(sc->sc_width)); OF_getprop(node, "linebytes", &sc->sc_stride, sizeof(sc->sc_stride)); /* * Get the PCI addresses of the adapter. The node may be the * child of the PCI device: in that case, try the parent for * the assigned-addresses property. */ len = OF_getprop(node, "assigned-addresses", sc->sc_pciaddrs, sizeof(sc->sc_pciaddrs)); if (len == -1) { len = OF_getprop(OF_parent(node), "assigned-addresses", sc->sc_pciaddrs, sizeof(sc->sc_pciaddrs)); } if (len == -1) len = 0; sc->sc_num_pciaddrs = len / sizeof(struct ofw_pci_register); /* * Grab the physical address of the framebuffer, and then map it * into our memory space. If the MMU is not yet up, it will be * remapped for us when relocation turns on. * * XXX We assume #address-cells is 1 at this point. */ if (OF_getproplen(node, "address") == sizeof(fb_phys)) { OF_getprop(node, "address", &fb_phys, sizeof(fb_phys)); sc->sc_tag = &bs_be_tag; bus_space_map(sc->sc_tag, fb_phys, sc->sc_height * sc->sc_stride, BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_addr); } else { /* * Some IBM systems don't have an address property. Try to * guess the framebuffer region from the assigned addresses. * This is ugly, but there doesn't seem to be an alternative. * Linux does the same thing. */ fb_phys = sc->sc_num_pciaddrs; for (i = 0; i < sc->sc_num_pciaddrs; i++) { /* If it is too small, not the framebuffer */ if (sc->sc_pciaddrs[i].size_lo < sc->sc_stride*sc->sc_height) continue; /* If it is not memory, it isn't either */ if (!(sc->sc_pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_SPACE_MEM32)) continue; /* This could be the framebuffer */ fb_phys = i; /* If it is prefetchable, it certainly is */ if (sc->sc_pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) break; } if (fb_phys == sc->sc_num_pciaddrs) return (0); OF_decode_addr(node, fb_phys, &sc->sc_tag, &sc->sc_addr); } ofwfb_init(0, &sc->sc_va, 0); return (0); } static int ofwfb_probe(int unit, video_adapter_t **adp, void *arg, int flags) { TODO; return (0); } static int ofwfb_init(int unit, video_adapter_t *adp, int flags) { struct ofwfb_softc *sc; video_info_t *vi; int cborder; int font_height; sc = (struct ofwfb_softc *)adp; vi = &adp->va_info; vid_init_struct(adp, "ofwfb", -1, unit); /* The default font size can be overridden by loader */ font_height = 16; TUNABLE_INT_FETCH("hw.syscons.fsize", &font_height); if (font_height == 8) { sc->sc_font = dflt_font_8; sc->sc_font_height = 8; } else if (font_height == 14) { sc->sc_font = dflt_font_14; sc->sc_font_height = 14; } else { /* default is 8x16 */ sc->sc_font = dflt_font_16; sc->sc_font_height = 16; } /* The user can set a border in chars - default is 1 char width */ cborder = 1; TUNABLE_INT_FETCH("hw.syscons.border", &cborder); vi->vi_cheight = sc->sc_font_height; vi->vi_width = sc->sc_width/8 - 2*cborder; vi->vi_height = sc->sc_height/sc->sc_font_height - 2*cborder; vi->vi_cwidth = 8; /* * Clamp width/height to syscons maximums */ if (vi->vi_width > COL) vi->vi_width = COL; if (vi->vi_height > ROW) vi->vi_height = ROW; sc->sc_xmargin = (sc->sc_width - (vi->vi_width * vi->vi_cwidth)) / 2; sc->sc_ymargin = (sc->sc_height - (vi->vi_height * vi->vi_cheight))/2; /* * Avoid huge amounts of conditional code in syscons by * defining a dummy h/w text display buffer. */ adp->va_window = (vm_offset_t) ofwfb_static_window; /* - * Enable future font-loading and flag color support, as well as + * Enable future font-loading and flag color support, as well as * adding V_ADP_MODECHANGE so that we ofwfb_set_mode() gets called * when the X server shuts down. This enables us to get the console * back when X disappears. */ adp->va_flags |= V_ADP_FONT | V_ADP_COLOR | V_ADP_MODECHANGE; ofwfb_set_mode(&sc->sc_va, 0); vid_register(&sc->sc_va); return (0); } static int ofwfb_get_info(video_adapter_t *adp, int mode, video_info_t *info) { bcopy(&adp->va_info, info, sizeof(*info)); return (0); } static int ofwfb_query_mode(video_adapter_t *adp, video_info_t *info) { TODO; return (0); } static int ofwfb_set_mode(video_adapter_t *adp, int mode) { struct ofwfb_softc *sc; char name[64]; ihandle_t ih; int i, retval; sc = (struct ofwfb_softc *)adp; if (ofwfb_reset_on_switch) { /* * Open the display device, which will initialize it. */ memset(name, 0, sizeof(name)); OF_package_to_path(sc->sc_node, name, sizeof(name)); ih = OF_open(name); if (sc->sc_depth == 8) { /* * Install the ISO6429 colormap - older OFW systems * don't do this by default */ for (i = 0; i < 16; i++) { OF_call_method("color!", ih, 4, 1, ofwfb_cmap[i].red, ofwfb_cmap[i].green, ofwfb_cmap[i].blue, i, &retval); } } } ofwfb_blank_display(&sc->sc_va, V_DISPLAY_ON); return (0); } static int ofwfb_save_font(video_adapter_t *adp, int page, int size, int width, u_char *data, int c, int count) { TODO; return (0); } static int ofwfb_load_font(video_adapter_t *adp, int page, int size, int width, u_char *data, int c, int count) { struct ofwfb_softc *sc; sc = (struct ofwfb_softc *)adp; /* * syscons code has already determined that current width/height * are unchanged for this new font */ sc->sc_font = data; return (0); } static int ofwfb_show_font(video_adapter_t *adp, int page) { return (0); } static int ofwfb_save_palette(video_adapter_t *adp, u_char *palette) { /* TODO; */ return (0); } static int ofwfb_load_palette(video_adapter_t *adp, u_char *palette) { /* TODO; */ return (0); } static int ofwfb_set_border8(video_adapter_t *adp, int border) { struct ofwfb_softc *sc; int i, j; uint8_t *addr; uint8_t bground; sc = (struct ofwfb_softc *)adp; bground = ofwfb_background(border); /* Set top margin */ addr = (uint8_t *) sc->sc_addr; for (i = 0; i < sc->sc_ymargin; i++) { for (j = 0; j < sc->sc_width; j++) { *(addr + j) = bground; } addr += sc->sc_stride; } /* bottom margin */ addr = (uint8_t *) sc->sc_addr + (sc->sc_height - sc->sc_ymargin)*sc->sc_stride; for (i = 0; i < sc->sc_ymargin; i++) { for (j = 0; j < sc->sc_width; j++) { *(addr + j) = bground; } addr += sc->sc_stride; } /* remaining left and right borders */ addr = (uint8_t *) sc->sc_addr + sc->sc_ymargin*sc->sc_stride; for (i = 0; i < sc->sc_height - 2*sc->sc_xmargin; i++) { for (j = 0; j < sc->sc_xmargin; j++) { *(addr + j) = bground; *(addr + j + sc->sc_width - sc->sc_xmargin) = bground; } addr += sc->sc_stride; } return (0); } static int ofwfb_set_border32(video_adapter_t *adp, int border) { /* XXX Be lazy for now and blank entire screen */ return (ofwfb_blank_display32(adp, border)); } static int ofwfb_set_border(video_adapter_t *adp, int border) { struct ofwfb_softc *sc; sc = (struct ofwfb_softc *)adp; return ((*sc->sc_set_border)(adp, border)); } static int ofwfb_save_state(video_adapter_t *adp, void *p, size_t size) { TODO; return (0); } static int ofwfb_load_state(video_adapter_t *adp, void *p) { TODO; return (0); } static int ofwfb_set_win_org(video_adapter_t *adp, off_t offset) { TODO; return (0); } static int ofwfb_read_hw_cursor(video_adapter_t *adp, int *col, int *row) { *col = 0; *row = 0; return (0); } static int ofwfb_set_hw_cursor(video_adapter_t *adp, int col, int row) { return (0); } static int ofwfb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height, int celsize, int blink) { return (0); } static int ofwfb_blank_display8(video_adapter_t *adp, int mode) { struct ofwfb_softc *sc; int i; uint32_t *addr; uint32_t color; uint32_t end; sc = (struct ofwfb_softc *)adp; addr = (uint32_t *) sc->sc_addr; end = (sc->sc_stride/4) * sc->sc_height; /* Splat 4 pixels at once. */ color = (ofwfb_background(SC_NORM_ATTR) << 24) | (ofwfb_background(SC_NORM_ATTR) << 16) | (ofwfb_background(SC_NORM_ATTR) << 8) | (ofwfb_background(SC_NORM_ATTR)); for (i = 0; i < end; i++) *(addr + i) = color; return (0); } static int ofwfb_blank_display32(video_adapter_t *adp, int mode) { struct ofwfb_softc *sc; int i; uint32_t *addr, blank; sc = (struct ofwfb_softc *)adp; addr = (uint32_t *) sc->sc_addr; blank = ofwfb_pix32(sc, ofwfb_background(SC_NORM_ATTR)); for (i = 0; i < (sc->sc_stride/4)*sc->sc_height; i++) *(addr + i) = blank; return (0); } static int ofwfb_blank_display(video_adapter_t *adp, int mode) { struct ofwfb_softc *sc; sc = (struct ofwfb_softc *)adp; return ((*sc->sc_blank)(adp, mode)); } static int ofwfb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr, int prot, vm_memattr_t *memattr) { struct ofwfb_softc *sc; int i; sc = (struct ofwfb_softc *)adp; /* * Make sure the requested address lies within the PCI device's * assigned addrs */ for (i = 0; i < sc->sc_num_pciaddrs; i++) if (offset >= sc->sc_pciaddrs[i].phys_lo && offset < (sc->sc_pciaddrs[i].phys_lo + sc->sc_pciaddrs[i].size_lo)) { /* * If this is a prefetchable BAR, we can (and should) * enable write-combining. */ if (sc->sc_pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) *memattr = VM_MEMATTR_WRITE_COMBINING; *paddr = offset; return (0); } /* * Hack for Radeon... */ if (ofwfb_ignore_mmap_checks) { *paddr = offset; return (0); } /* * This might be a legacy VGA mem request: if so, just point it at the * framebuffer, since it shouldn't be touched */ if (offset < sc->sc_stride*sc->sc_height) { *paddr = sc->sc_addr + offset; return (0); } /* * Error if we didn't have a better idea. */ if (sc->sc_num_pciaddrs == 0) return (ENOMEM); return (EINVAL); } static int ofwfb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data) { return (0); } static int ofwfb_clear(video_adapter_t *adp) { TODO; return (0); } static int ofwfb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) { TODO; return (0); } static int ofwfb_bitblt(video_adapter_t *adp, ...) { TODO; return (0); } static int ofwfb_diag(video_adapter_t *adp, int level) { TODO; return (0); } static int ofwfb_save_cursor_palette(video_adapter_t *adp, u_char *palette) { TODO; return (0); } static int ofwfb_load_cursor_palette(video_adapter_t *adp, u_char *palette) { TODO; return (0); } static int ofwfb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n) { TODO; return (0); } static int ofwfb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a, int size, int bpp, int bit_ltor, int byte_ltor) { TODO; return (0); } static int ofwfb_putc8(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a) { struct ofwfb_softc *sc; int row; int col; int i; uint32_t *addr; u_char *p, fg, bg; union { uint32_t l; uint8_t c[4]; } ch1, ch2; sc = (struct ofwfb_softc *)adp; row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight; col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth; p = sc->sc_font + c*sc->sc_font_height; addr = (u_int32_t *)((uintptr_t)sc->sc_addr + (row + sc->sc_ymargin)*sc->sc_stride + col + sc->sc_xmargin); fg = ofwfb_foreground(a); bg = ofwfb_background(a); for (i = 0; i < sc->sc_font_height; i++) { u_char fline = p[i]; /* * Assume that there is more background than foreground * in characters and init accordingly */ ch1.l = ch2.l = (bg << 24) | (bg << 16) | (bg << 8) | bg; /* * Calculate 2 x 4-chars at a time, and then * write these out. */ if (fline & 0x80) ch1.c[0] = fg; if (fline & 0x40) ch1.c[1] = fg; if (fline & 0x20) ch1.c[2] = fg; if (fline & 0x10) ch1.c[3] = fg; if (fline & 0x08) ch2.c[0] = fg; if (fline & 0x04) ch2.c[1] = fg; if (fline & 0x02) ch2.c[2] = fg; if (fline & 0x01) ch2.c[3] = fg; addr[0] = ch1.l; addr[1] = ch2.l; addr += (sc->sc_stride / sizeof(u_int32_t)); } return (0); } static int ofwfb_putc32(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a) { struct ofwfb_softc *sc; int row; int col; int i, j, k; uint32_t *addr, fg, bg; u_char *p; sc = (struct ofwfb_softc *)adp; row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight; col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth; p = sc->sc_font + c*sc->sc_font_height; addr = (uint32_t *)sc->sc_addr + (row + sc->sc_ymargin)*(sc->sc_stride/4) + col + sc->sc_xmargin; - + fg = ofwfb_pix32(sc, ofwfb_foreground(a)); bg = ofwfb_pix32(sc, ofwfb_background(a)); for (i = 0; i < sc->sc_font_height; i++) { for (j = 0, k = 7; j < 8; j++, k--) { if ((p[i] & (1 << k)) == 0) *(addr + j) = bg; else *(addr + j) = fg; } addr += (sc->sc_stride/4); } return (0); } static int ofwfb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a) { struct ofwfb_softc *sc; sc = (struct ofwfb_softc *)adp; return ((*sc->sc_putc)(adp, off, c, a)); } static int ofwfb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len) { int i; for (i = 0; i < len; i++) { ofwfb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8); } return (0); } static int ofwfb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image, uint32_t pixel_mask, int size, int width) { struct ofwfb_softc *sc; sc = (struct ofwfb_softc *)adp; return ((*sc->sc_putm)(adp, x, y, pixel_image, pixel_mask, size, width)); } static int ofwfb_putm8(video_adapter_t *adp, int x, int y, uint8_t *pixel_image, uint32_t pixel_mask, int size, int width) { struct ofwfb_softc *sc; int i, j, k; uint8_t *addr; u_char fg, bg; sc = (struct ofwfb_softc *)adp; addr = (u_int8_t *)((uintptr_t)sc->sc_addr + (y + sc->sc_ymargin)*sc->sc_stride + x + sc->sc_xmargin); fg = ofwfb_foreground(SC_NORM_ATTR); bg = ofwfb_background(SC_NORM_ATTR); for (i = 0; i < size && i+y < sc->sc_height - 2*sc->sc_ymargin; i++) { /* * Calculate 2 x 4-chars at a time, and then * write these out. */ for (j = 0, k = width; j < 8; j++, k--) { if (x + j >= sc->sc_width - 2*sc->sc_xmargin) continue; if (pixel_image[i] & (1 << k)) addr[j] = (addr[j] == fg) ? bg : fg; } addr += (sc->sc_stride / sizeof(u_int8_t)); } return (0); } static int ofwfb_putm32(video_adapter_t *adp, int x, int y, uint8_t *pixel_image, uint32_t pixel_mask, int size, int width) { struct ofwfb_softc *sc; int i, j, k; uint32_t fg, bg; uint32_t *addr; sc = (struct ofwfb_softc *)adp; addr = (uint32_t *)sc->sc_addr + (y + sc->sc_ymargin)*(sc->sc_stride/4) + x + sc->sc_xmargin; fg = ofwfb_pix32(sc, ofwfb_foreground(SC_NORM_ATTR)); bg = ofwfb_pix32(sc, ofwfb_background(SC_NORM_ATTR)); for (i = 0; i < size && i+y < sc->sc_height - 2*sc->sc_ymargin; i++) { for (j = 0, k = width; j < 8; j++, k--) { if (x + j >= sc->sc_width - 2*sc->sc_xmargin) continue; if (pixel_image[i] & (1 << k)) *(addr + j) = (*(addr + j) == fg) ? bg : fg; } addr += (sc->sc_stride/4); } return (0); } /* * Define the syscons nexus device attachment */ static void ofwfb_scidentify(driver_t *driver, device_t parent) { device_t child; /* - * The Nintendo Wii doesn't have open firmware, so don't probe ofwfb - * because otherwise we will crash. - */ - if (strcmp(installed_platform(), "wii") == 0) - return; - /* * Add with a priority guaranteed to make it last on * the device list */ child = BUS_ADD_CHILD(parent, INT_MAX, SC_DRIVER_NAME, 0); } static int ofwfb_scprobe(device_t dev) { int error; device_set_desc(dev, "System console"); - error = sc_probe_unit(device_get_unit(dev), + error = sc_probe_unit(device_get_unit(dev), device_get_flags(dev) | SC_AUTODETECT_KBD); if (error != 0) return (error); /* This is a fake device, so make sure we added it ourselves */ return (BUS_PROBE_NOWILDCARD); } static int ofwfb_scattach(device_t dev) { return (sc_attach_unit(device_get_unit(dev), device_get_flags(dev) | SC_AUTODETECT_KBD)); } static device_method_t ofwfb_sc_methods[] = { DEVMETHOD(device_identify, ofwfb_scidentify), DEVMETHOD(device_probe, ofwfb_scprobe), DEVMETHOD(device_attach, ofwfb_scattach), { 0, 0 } }; static driver_t ofwfb_sc_driver = { SC_DRIVER_NAME, ofwfb_sc_methods, sizeof(sc_softc_t), }; static devclass_t sc_devclass; DRIVER_MODULE(ofwfb, nexus, ofwfb_sc_driver, sc_devclass, 0, 0); /* * Define a stub keyboard driver in case one hasn't been * compiled into the kernel */ #include #include static int dummy_kbd_configure(int flags); keyboard_switch_t dummysw; static int dummy_kbd_configure(int flags) { return (0); } KEYBOARD_DRIVER(dummy, dummysw, dummy_kbd_configure); /* * Utility routines from */ void ofwfb_bcopy(const void *s, void *d, size_t c) { bcopy(s, d, c); } void ofwfb_bzero(void *d, size_t c) { bzero(d, c); } void ofwfb_fillw(int pat, void *base, size_t cnt) { u_int16_t *bptr = base; while (cnt--) *bptr++ = pat; } u_int16_t ofwfb_readw(u_int16_t *addr) { return (*addr); } void ofwfb_writew(u_int16_t *addr, u_int16_t val) { *addr = val; }