root/sys/arch/evbppc/nintendo/mmuinit.S
/* $NetBSD: mmuinit.S,v 1.2 2026/01/10 22:45:57 jmcneill Exp $ */

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

#include <powerpc/oea/bat.h>

/*
 * When we are invoked from Wii loaders, the state of the MMU and the BAT
 * mappings can vary.  In this file we try to reset the MMU to a state
 * that lets us boot NetBSD.
 *
 * This file is being included from wii_locore.S.
 */

#define MMU_REALMODE()                          \
        mfmsr   %r12;                           \
        rlwinm  %r12, %r12, 0, ~(PSL_DR|PSL_IR);\
        sync;                                   \
        bl      1f;                             \
1:                                              \
        mflr    %r11;                           \
        clrlwi  %r11, %r11, 3;  /* XXX why? */  \
        addi    %r11, %r11, 2f - 1b;            \
        mtsrr0  %r11;                           \
        mtsrr1  %r12;   /* Disables the MMU */  \
        isync;                                  \
        rfi;                                    \
2:

#define MMU_VIRTUALMODE()                       \
        bl      3f;                             \
3:                                              \
        mflr    %r11;                           \
        addi    %r11, %r11, 4f - 3b;            \
        mfmsr   %r12;                           \
        ori     %r12, %r12, PSL_DR|PSL_IR;      \
        mtsrr0  %r11;                           \
        mtsrr1  %r12;   /* Enables the MMU */   \
        isync;                                  \
        rfi;                                    \
4:

        MMU_REALMODE()

        /* Initialize HID0 and HID4 */
        lis     %r11, 0x0011
        ori     %r11, %r11, 0x0c64
        mtspr   SPR_HID0, %r11
        isync

        lis     %r11, 0x8200
        mtspr   1011, %r11      /* 1011 = SPR_HID4 */
        isync

        mfspr   %r11, 920
        oris    %r11, %r11, 0xa000
        mtspr   920, %r11

        mfspr   %r11, SPR_HID0
        ori     %r11, %r11, 0xc000
        ori     %r11, %r11, 0x0800
        ori     %r11, %r11, 0x0200
        mtspr   SPR_HID0, %r11
        isync

        /* 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_32M, BAT_Vs)
        li      %r12, BATL(0x00000000, BAT_M, BAT_PP_RW)
        mtdbatu 0, %r11
        mtdbatl 0, %r12
        mtibatu 0, %r11
        mtibatl 0, %r12
        isync

        /*
         * Use BAT1 to access MEM2.
         */
        /* BATU(0x10000000, BAT_BL_256M, BAT_Vs) */
        lis     %r11, 0x1000
        ori     %r11, %r11, BAT_BL_256M|BAT_Vs
        /* BATL(0x10000000, BAT_M, BAT_PP_RW) */
        lis     %r12, 0x1000
        ori     %r12, %r12, BAT_M|BAT_PP_RW
        mtdbatu 1, %r11
        mtdbatl 1, %r12
        isync

        /*
         * We use BAT2 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 2, %r11
        mtdbatl 2, %r12
        isync

        /*
         * BAT3 is used to access loader data (kernel cmdline) on Wii U.
         */
        /* BATU(0x89000000, BAT_BL_8M, BAT_Vs) */
        lis     %r11, 0x8900
        ori     %r11, %r11, BAT_BL_8M|BAT_Vs
        /* BATL(0x89000000, BAT_M, BAT_PP_RW) */
        lis     %r12, 0x8900
        ori     %r12, %r12, BAT_M|BAT_PP_RW
        mtdbatu 1, %r11
        mtdbatl 1, %r12
        isync

        MMU_VIRTUALMODE()