/*      $NetBSD: mmu_51.h,v 1.4 2024/02/08 20:11:56 andvar Exp $        */

/*-
* Copyright (c) 1997, 2023 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jeremy Cooper and by Jason R. Thorpe.
*
* 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.
*/

#ifndef _M68K_MMU_51_H_
#define _M68K_MMU_51_H_

/*
* Translation table structures for the 68851 MMU.
*
* The 68851 MMU (as well as the 68030's built-in MMU) are pretty flexible and
* can use a 1, 2, 3, or 4-level tree structure and a number of page sizes.
*
* The logical address format is defined as:
*
*  31                                                                0
* |        |          |          |          |          |              |
*  SSSSSSSS AAAAAAAAAA BBBBBBBBBB CCCCCCCCCC DDDDDDDDDD PPPPPPPPPPPPPP
*  Initial   A Index    B Index    C Index    D Index    Page Offset
*   Shift
*
* The Initial Shift, and number of A, B, C, and D index bits are defined
* in the Translation Control register.  Once the MMU encounters a tree
* level where the number of index bits is 0, tree traversal stops.  The
* values of IS + TIA + TIB + TIC + TID + page offset must equal 32.  For
* example, for a 2-level arrangment using 4KB pages where all 32-bits of
* the address are significant:
*
*     IS  TIA  TIB  TIC  TID  page
*      0 + 10 + 10 +  0 +  0 +  12 == 32
*/

/*
* The 68851 has 3 descriptor formats:
*
*      Long Table Descriptors          (8 byte)
*      Short Table Descriptors         (4 byte)
*      Page Descriptors                (4 byte)
*
* These occupy the lower 2 bits of each descriptor and the root pointers.
*/
#define DT51_INVALID    0
#define DT51_PAGE       1       /* points to a page */
#define DT51_SHORT      2       /* points to a short entry table */
#define DT51_LONG       3       /* points to a long entry table */

/*
* Long Format Table Descriptor
*
*  63                                                             48
*  +---+---.---.---.---.---.---.---.---.---.---.---.---.---.---.---+
*  |L/U|                 LIMIT                                     |
*  +---+---.---+---.---.---+---+---+---+---+---+---+---+---+---.---+
*  |    RAL    |    WAL    |SG | S | 0 | 0 | 0 | 0 | U |WP |  DT   |
*  +---.---.---+---.---.---+---+---+---+---+---+---+---+---+---.---+
*  |              TABLE PHYSICAL ADDRESS (BITS 31-16)              |
*  +---.---.---.---.---.---.---.---.---.---.---.---+---.---.---.---+
*  |       TABLE PHYSICAL ADDRESS (15-4)           |     UNUSED    |
*  +---.---.---.---.---.---.---.---.---.---.---.---+---.---.---.---+
*  15                                                              0
*
* DT is either 2 or 3, depending on what next table descriptor format is.
*/
struct mmu51_ldte {             /* 'dte' stands for 'descriptor table entry' */
       uint32_t        ldte_attr;
       uint32_t        ldte_addr;
};
#define DTE51_ADDR      __BITS(4,31)    /* table address mask */
#define DTE51_LOWER     __BIT(31)       /* L: Index limit is lower limit */
#define DTE51_LIMIT     __BITS(16,30)   /* L: Index limit */
#define DTE51_RAL       __BITS(13,15)   /* L: Read Access Level */
#define DTE51_WAL       __BITS(10,12)   /* L: Write Access Level */
#define DTE51_SG        __BIT(9)        /* L: Shared Globally */
#define DTE51_S         __BIT(8)        /* L: Supervisor protected */
#define DTE51_U         __BIT(3)        /* Used */
#define DTE51_WP        __BIT(2)        /* Write Protected */

/*
* Short Format Table Descriptor
*
* 31                                                             16
* +---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---+
* |           TABLE PHYSICAL BASE ADDRESS (BITS 31-16)            |
* +---.---.---.---.---.---.---.---.---.---.---.---+---+---+---.---+
* | TABLE PHYSICAL BASE ADDRESS (15-4)            | U |WP |  DT   |
* +---.---.---.---.---.---.---.---.---.---.---.---+---+---+---.---+
* 15                                                              0
*
* DT is either 2 or 3, depending on what next table descriptor format is.
*/

/*
* Long Format Page Descriptor (Level A table only)
*
*  63                                                             48
*  +---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---+
*  |                          UNUSED                               |
*  +---.---.---+---.---.---+---+---+---+---+---+---+---+---+---.---+
*  |    RAL    |    WAL    |SG | S | G |CI | L | M | U |WP |DT (01)|
*  +---.---.---+---.---.---+---+---+---+---+---+---+---+---+---.---+
*  |               PAGE PHYSICAL ADDRESS (BITS 31-16)              |
*  +---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---+
*  | PAGE PHYS. ADDRESS (15-8)     |            UNUSED             |
*  +---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---+
*  15                                                              0
*
* N.B. Unused bits of the page address (if the page size is larger
* than 256 bytes) can be used as software-defined PTE bits.
*/
struct mmu51_lpte {             /* 'pte' stands for 'page table entry' */
       uint32_t        lpte_attr;
       uint32_t        lpte_addr;
};
#define PTE51_ADDR      __BITS(8,31)    /* page address mask */
#define PTE51_RAL       __BITS(13,15)   /* L: Read Access Level */
#define PTE51_WAL       __BITS(10,12)   /* L: Write Access Level */
#define PTE51_SG        __BIT(9)        /* L: Shared Globally */
#define PTE51_S         __BIT(8)        /* L: Supervisor protected */
#define PTE51_G         __BIT(7)        /* Gate allowed */
#define PTE51_CI        __BIT(6)        /* Cache inhibit */
#define PTE51_L         __BIT(5)        /* Lock entry */
#define PTE51_M         __BIT(4)        /* Modified */
#define PTE51_U         __BIT(3)        /* Used */
#define PTE51_WP        __BIT(2)        /* Write Protected */

/*
* Short Format Page Descriptor
*
* 31                                                             16
* +---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---+
* |            PAGE PHYSICAL BASE ADDRESS (BITS 31-16)            |
* +---.---.---.---.---.---.---.---+---+---+---+---+---+---+---.---+
* | PAGE PHYS. BASE ADDRESS (15-8)| G |CI | L | M | U |WP |DT (01)|
* +---.---.---.---.---.---.---.---+---+---+---+---+---+---+---.---+
* 15                                                              0
*
* N.B. Unused bits of the page address (if the page size is larger
* than 256 bytes) can be used as software-defined PTE bits.
*/

/*
* MMU registers (and the sections in the 68851 manual that
* describe them).
*/

/*
* 5.1.4 -- Root Pointer
* (and also 6.1.1)
*
* This is a 64-bit register.  The upper 32 bits contain configuration
* information, and the lower 32 bits contain the A table address.
* Bits 3-0 of the address must be 0.  The root pointer is essentially
* a long format table descriptor with only the U/L, limit, and SG bits.
*
* The 68851 has 3 root pointers:
*
* CRP          CPU root pointer, for user accesses
* SRP          Supervisor root pointer
* DRP          DMA root pointer, for IOMMU functionality (not on '030)
*
* Selection of root pointer is as follows:
*
*      FC3     FC2     SRE             Root pointer used
*       0       0       0                    CRP
*       0       0       1                    CRP
*       0       1       0                    CRP
*       0       1       1                    SRP
*       1       x       x                    DRP
*/
struct mmu51_rootptr {
       unsigned long   rp_attr;        /* Lower/Upper Limit and access flags */
       unsigned long   rp_addr;        /* Physical Base Address */
};

/*
* 6.1.2 -- PMMU Cache Status (PCSR) (16-bit)
*/
#define PCSR51_F        __BIT(15)       /* Flush(ed) */
#define PCSR51_LW       __BIT(14)       /* Lock Warning */
#define PCSR51_TA       __BITS(0,2)     /* Task Alias (not '030) */

/*
* 6.1.3 -- Translation Control (TCR) (32-bit)
*/
#define TCR51_E         __BIT(31)       /* Enable translation */
#define TCR51_SRE       __BIT(25)       /* Supervisor Root Enable */
#define TCR51_FCL       __BIT(24)       /* Function Code Lookup */
#define TCR51_PS        __BITS(20,23)   /* Page Size (see below) */
#define TCR51_IS        __BITS(16,19)   /* Initial Shift */
#define TCR51_TIA       __BITS(12,15)   /* Table A Index bits */
#define TCR51_TIB       __BITS(8,11)    /* Table B Index bits */
#define TCR51_TIC       __BITS(4,7)     /* Table C Index bits */
#define TCR51_TID       __BITS(0,3)     /* Table D Index bits */

/*
* Astute readers will note that the value in the PS field is
* log2(PAGE_SIZE).
*/
#define TCR51_PS_256    __SHIFTIN(0x8, TCR51_PS)
#define TCR51_PS_512    __SHIFTIN(0x9, TCR51_PS)
#define TCR51_PS_1K     __SHIFTIN(0xa, TCR51_PS)
#define TCR51_PS_2K     __SHIFTIN(0xb, TCR51_PS)
#define TCR51_PS_4K     __SHIFTIN(0xc, TCR51_PS)
#define TCR51_PS_8K     __SHIFTIN(0xd, TCR51_PS)
#define TCR51_PS_16K    __SHIFTIN(0xe, TCR51_PS)
#define TCR51_PS_32K    __SHIFTIN(0xf, TCR51_PS)

/*
* 6.1.4 -- Current Access Level (8-bit)
* 6.1.5 -- Validate Access Level
*/
#define CAL51_AL        __BITS(5,7)

/*
* 6.1.6 -- Stack Change Control (8-bit)
*/

/*
* 6.1.7 -- Access Control (16-bit)
*/
#define AC51_MC         __BIT(7)        /* Module Control */
#define AC51_ALC        __BITS(4,5)     /* Access Level Control */
#define AC51_MDS        __BITS(0,1)     /* Module Descriptor Size */

/*
* 6.1.8 -- PMMU Status Register (PSR) (16-bit)
*/
#define PSR51_B         __BIT(15)       /* Bus Error */
#define PSR51_L         __BIT(14)       /* Limit Violation */
#define PSR51_S         __BIT(13)       /* Supervisor Violation */
#define PSR51_A         __BIT(12)       /* Access Level Violation */
#define PSR51_W         __BIT(11)       /* Write Protected */
#define PSR51_I         __BIT(10)       /* Invalid */
#define PSR51_M         __BIT(9)        /* Modified */
#define PSR51_G         __BIT(8)        /* Gate */
#define PSR51_C         __BIT(7)        /* Globally Shareable */
#define PSR51_N         __BITS(0,2)     /* Number of levels */

#ifdef _KERNEL
extern unsigned int protorp[2];

void    mmu_load_urp51(paddr_t);
void    mmu_load_urp20hp(paddr_t);      /* for convenience */
#endif /* _KERNEL */

#endif /* _M68K_MMU_51_H_ */