Annotation of previous/src/cpu/cpummu.h, revision 1.1.1.2

1.1.1.2 ! root        1: /*
        !             2:  * cpummu.h - MMU emulation
        !             3:  *
        !             4:  * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS)
        !             5:  * 
        !             6:  * Inspired by UAE MMU patch
        !             7:  *
        !             8:  * This file is part of the ARAnyM project which builds a new and powerful
        !             9:  * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
        !            10:  *
        !            11:  * ARAnyM is free software; you can redistribute it and/or modify
        !            12:  * it under the terms of the GNU General Public License as published by
        !            13:  * the Free Software Foundation; either version 2 of the License, or
        !            14:  * (at your option) any later version.
        !            15:  *
        !            16:  * ARAnyM is distributed in the hope that it will be useful,
        !            17:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            18:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            19:  * GNU General Public License for more details.
        !            20:  *
        !            21:  * You should have received a copy of the GNU General Public License
        !            22:  * along with ARAnyM; if not, write to the Free Software
        !            23:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        !            24:  */
        !            25: 
        !            26: #ifndef CPUMMU_H
        !            27: #define CPUMMU_H
        !            28: 
        !            29: #include "compat.h"
        !            30: 
        !            31: #ifndef FULLMMU
        !            32: #define FULLMMU
        !            33: #endif
        !            34: 
        !            35: #define DUNUSED(x)
        !            36: #define D
        !            37: #if DEBUG
        !            38: #define bug write_log
        !            39: #else
        !            40: #define bug
        !            41: #endif
        !            42: 
        !            43: #if 0
        !            44: struct m68k_exception {
        !            45:        int prb;
        !            46:        m68k_exception (int exc) : prb (exc) {}
        !            47:        operator int() { return prb; }
        !            48: };
        !            49: #define SAVE_EXCEPTION
        !            50: #define RESTORE_EXCEPTION
        !            51: #define TRY(var) try
        !            52: #define CATCH(var) catch(m68k_exception var)
        !            53: #define THROW(n) throw m68k_exception(n)
        !            54: #define THROW_AGAIN(var) throw
        !            55: 
        !            56: #else
        !            57: /* we are in plain C, just use a stack of long jumps */
        !            58: #include <setjmp.h>
        !            59: extern jmp_buf __exbuf;
        !            60: extern int     __exvalue;
        !            61: #define TRY(DUMMY)       __exvalue=setjmp(__exbuf);       \
        !            62:                   if (__exvalue==0) { __pushtry(&__exbuf);
        !            63: #define CATCH(x)  __poptry(); } else { fprintf(stderr,"Gotcha! %d %s in %d\n",__exvalue,__FILE__,__LINE__); __poptry();
        !            64: #define ENDTRY    }
        !            65: #define THROW(x) if (__is_catched()) {fprintf(stderr,"Longjumping %s in %d\n",__FILE__,__LINE__);longjmp(__exbuf,x);} else fprintf(stderr,"/!\\ cannot Longjumping %s in %d\n",__FILE__,__LINE__)
        !            66: #define THROW_AGAIN(var) if (__is_catched()) longjmp(__exbuf,__exvalue); else fprintf(stderr,"/!\\ cannot Longjumping %s in %d\n",__FILE__,__LINE__)
        !            67: #define SAVE_EXCEPTION
        !            68: #define RESTORE_EXCEPTION
        !            69: jmp_buf* __poptry(void);
        !            70: void __pushtry(jmp_buf *j);
        !            71: int __is_catched(void);
        !            72: 
        !            73: typedef  int m68k_exception;
        !            74: 
        !            75: #endif
        !            76: 
        !            77: #define VOLATILE
        !            78: #define ALWAYS_INLINE __inline
        !            79: 
        !            80: static __inline void flush_internals (void) { }
        !            81: 
        !            82: //typedef uae_u8 flagtype;
        !            83: 
        !            84: //static m68k_exception except;
        !            85: 
        !            86: struct xttrx {
        !            87:     uae_u32 log_addr_base : 8;
        !            88:     uae_u32 log_addr_mask : 8;
        !            89:     uae_u32 enable : 1;
        !            90:     uae_u32 s_field : 2;
        !            91:     uae_u32 : 3;
        !            92:     uae_u32 usr1 : 1;
        !            93:     uae_u32 usr0 : 1;
        !            94:     uae_u32 : 1;
        !            95:     uae_u32 cmode : 2;
        !            96:     uae_u32 : 2;
        !            97:     uae_u32 write : 1;
        !            98:     uae_u32 : 2;
        !            99: };
        !           100: 
        !           101: struct mmusr_t {
        !           102:    uae_u32 phys_addr : 20;
        !           103:    uae_u32 bus_err : 1;
        !           104:    uae_u32 global : 1;
        !           105:    uae_u32 usr1 : 1;
        !           106:    uae_u32 usr0 : 1;
        !           107:    uae_u32 super : 1;
        !           108:    uae_u32 cmode : 2;
        !           109:    uae_u32 modif : 1;
        !           110:    uae_u32 : 1;
        !           111:    uae_u32 write : 1;
        !           112:    uae_u32 ttrhit : 1;
        !           113:    uae_u32 resident : 1;
        !           114: };
        !           115: 
        !           116: struct log_addr4 {
        !           117:    uae_u32 rif : 7;
        !           118:    uae_u32 pif : 7;
        !           119:    uae_u32 paif : 6;
        !           120:    uae_u32 poff : 12;
        !           121: };
        !           122: 
        !           123: struct log_addr8 {
        !           124:   uae_u32 rif : 7;
        !           125:   uae_u32 pif : 7;
        !           126:   uae_u32 paif : 5;
        !           127:   uae_u32 poff : 13;
        !           128: };
        !           129: 
        !           130: #define MMU_TEST_PTEST                                 1
        !           131: #define MMU_TEST_VERBOSE                               2
        !           132: #define MMU_TEST_FORCE_TABLE_SEARCH            4
        !           133: #define MMU_TEST_NO_BUSERR                             8
        !           134: 
        !           135: extern void mmu_dump_tables(void);
        !           136: 
        !           137: #define MMU_TTR_LOGICAL_BASE                           0xff000000
        !           138: #define MMU_TTR_LOGICAL_MASK                           0x00ff0000
        !           139: #define MMU_TTR_BIT_ENABLED                                    (1 << 15)
        !           140: #define MMU_TTR_BIT_SFIELD_ENABLED                     (1 << 14)
        !           141: #define MMU_TTR_BIT_SFIELD_SUPER                       (1 << 13)
        !           142: #define MMU_TTR_SFIELD_SHIFT                           13
        !           143: #define MMU_TTR_UX_MASK                                                ((1 << 9) | (1 << 8))
        !           144: #define MMU_TTR_UX_SHIFT                                       8
        !           145: #define MMU_TTR_CACHE_MASK                                     ((1 << 6) | (1 << 5))
        !           146: #define MMU_TTR_CACHE_SHIFT                                    5
        !           147: #define MMU_TTR_BIT_WRITE_PROTECT                      (1 << 2)
        !           148: 
        !           149: #define MMU_UDT_MASK   3
        !           150: #define MMU_PDT_MASK   3
        !           151: 
        !           152: #define MMU_DES_WP                     4
        !           153: #define MMU_DES_USED           8
        !           154: 
        !           155: /* page descriptors only */
        !           156: #define MMU_DES_MODIFIED       16
        !           157: #define MMU_DES_SUPER          (1 << 7)
        !           158: #define MMU_DES_GLOBAL         (1 << 10)
        !           159: 
        !           160: #define MMU_ROOT_PTR_ADDR_MASK                 0xfffffe00
        !           161: #define MMU_PTR_PAGE_ADDR_MASK_8               0xffffff80
        !           162: #define MMU_PTR_PAGE_ADDR_MASK_4               0xffffff00
        !           163: 
        !           164: #define MMU_PAGE_INDIRECT_MASK                 0xfffffffc
        !           165: #define MMU_PAGE_ADDR_MASK_8                   0xffffe000
        !           166: #define MMU_PAGE_ADDR_MASK_4                   0xfffff000
        !           167: #define MMU_PAGE_UR_MASK_8                             ((1 << 12) | (1 << 11))
        !           168: #define MMU_PAGE_UR_MASK_4                             (1 << 11)
        !           169: #define MMU_PAGE_UR_SHIFT                              11
        !           170: 
        !           171: #define MMU_MMUSR_ADDR_MASK                            0xfffff000
        !           172: #define MMU_MMUSR_B                                            (1 << 11)
        !           173: #define MMU_MMUSR_G                                            (1 << 10)
        !           174: #define MMU_MMUSR_U1                                   (1 << 9)
        !           175: #define MMU_MMUSR_U0                                   (1 << 8)
        !           176: #define MMU_MMUSR_Ux                                   (MMU_MMUSR_U1 | MMU_MMUSR_U0)
        !           177: #define MMU_MMUSR_S                                            (1 << 7)
        !           178: #define MMU_MMUSR_CM                                   ((1 << 6) | ( 1 << 5))
        !           179: #define MMU_MMUSR_M                                            (1 << 4)
        !           180: #define MMU_MMUSR_W                                            (1 << 2)
        !           181: #define MMU_MMUSR_T                                            (1 << 1)
        !           182: #define MMU_MMUSR_R                                            (1 << 0)
        !           183: 
        !           184: /* special status word (access error stack frame) */
        !           185: #define MMU_SSW_TM             0x0007
        !           186: #define MMU_SSW_TT             0x0018
        !           187: #define MMU_SSW_SIZE   0x0060
        !           188: #define MMU_SSW_SIZE_B 0x0020
        !           189: #define MMU_SSW_SIZE_W 0x0040
        !           190: #define MMU_SSW_SIZE_L 0x0000
        !           191: #define MMU_SSW_RW             0x0100
        !           192: #define MMU_SSW_LK             0x0200
        !           193: #define MMU_SSW_ATC            0x0400
        !           194: #define MMU_SSW_MA             0x0800
        !           195: #define MMU_SSW_CM     0x1000
        !           196: #define MMU_SSW_CT     0x2000
        !           197: #define MMU_SSW_CU     0x4000
        !           198: #define MMU_SSW_CP     0x8000
        !           199: 
        !           200: #define TTR_I0 4
        !           201: #define TTR_I1 5
        !           202: #define TTR_D0 6
        !           203: #define TTR_D1 7
        !           204: 
        !           205: #define TTR_NO_MATCH   0
        !           206: #define TTR_NO_WRITE   1
        !           207: #define TTR_OK_MATCH   2
        !           208: 
        !           209: struct mmu_atc_line {
        !           210:        uaecptr tag; // tag is 16 or 17 bits S+logical
        !           211:        unsigned valid : 1;
        !           212:        unsigned global : 1;
        !           213:        unsigned modified : 1;
        !           214:        unsigned write_protect : 1;
        !           215:        uaecptr phys; // phys base address
        !           216: };
        !           217: 
        !           218: /*
        !           219:  * 68040 ATC is a 4 way 16 slot associative address translation cache
        !           220:  * the 68040 has a DATA and an INSTRUCTION ATC.
        !           221:  * an ATC lookup may result in : a hit, a miss and a modified state.
        !           222:  * the 68060 can disable ATC allocation
        !           223:  * we must take care of 8k and 4k page size, index position is relative to page size
        !           224:  */
        !           225: 
        !           226: #define ATC_WAYS 4
        !           227: #define ATC_SLOTS 16
        !           228: #define ATC_TYPE 2
        !           229: 
        !           230: extern bool mmu_is_super;
        !           231: extern struct mmu_atc_line mmu_atc_array[ATC_TYPE][ATC_WAYS][ATC_SLOTS];
        !           232: 
        !           233: /*
        !           234:  * mmu access is a 4 step process:
        !           235:  * if mmu is not enabled just read physical
        !           236:  * check transparent region, if transparent, read physical
        !           237:  * check ATC (address translation cache), read immediatly if HIT
        !           238:  * read from mmu with the long path (and allocate ATC entry if needed)
        !           239:  */
        !           240: static ALWAYS_INLINE bool mmu_lookup(uaecptr addr, bool data, bool write,
        !           241:                                                                          struct mmu_atc_line **cl)
        !           242: {
        !           243:        int way,index;
        !           244:        static int way_miss=0;
        !           245: 
        !           246:        addr = ((mmu_is_super?0x80000000:0x00000000)|(addr >> 1)) & (regs.mmu_pagesize_8k?0xFFFE0000:0xFFFF0000);
        !           247:        if (regs.mmu_pagesize_8k)
        !           248:                index=(addr & 0x0001E000)>>13;
        !           249:        else
        !           250:                index=(addr & 0x0000F000)>>12;
        !           251:        for (way=0;way<ATC_WAYS;way++) {
        !           252:                // if we have this 
        !           253:                if ((addr == mmu_atc_array[data][way][index].tag) && (mmu_atc_array[data][way][index].valid)) {
        !           254:                        *cl=&mmu_atc_array[data][way][index];
        !           255:                        // if first write to this take slow path (but modify this slot)
        !           256:                        if ((!mmu_atc_array[data][way][index].modified & write) || (mmu_atc_array[data][way][index].write_protect & write))
        !           257:                                return false; 
        !           258:                        return true;
        !           259:                }
        !           260:        }
        !           261:        // we select a random way to void
        !           262:        *cl=&mmu_atc_array[data][way_miss%ATC_WAYS][index];
        !           263:        way_miss++;
        !           264:        return false;
        !           265: }
        !           266: 
        !           267: /*
        !           268:  */
        !           269: static ALWAYS_INLINE bool mmu_user_lookup(uaecptr addr, bool super, bool data,
        !           270:                                                                                   bool write, struct mmu_atc_line **cl)
        !           271: {
        !           272:        int way,index;
        !           273:        static int way_miss=0;
        !           274: 
        !           275:        addr = ((super?0x80000000:0x00000000)|(addr >> 1)) & (regs.mmu_pagesize_8k?0xFFFE0000:0xFFFF0000);
        !           276:        if (regs.mmu_pagesize_8k)
        !           277:                index=(addr & 0x0001E000)>>13;
        !           278:        else
        !           279:                index=(addr & 0x0000F000)>>12;
        !           280:        for (way=0;way<ATC_WAYS;way++) {
        !           281:                // if we have this 
        !           282:                if ((addr == mmu_atc_array[data][way][index].tag) && (mmu_atc_array[data][way][index].valid)) {
        !           283:                        *cl=&mmu_atc_array[data][way][index];
        !           284:                        // if first write to this take slow path (but modify this slot)
        !           285:                        if ((!mmu_atc_array[data][way][index].modified & write) || (mmu_atc_array[data][way][index].write_protect & write))
        !           286:                                return false; 
        !           287:                        return true;
        !           288:                }
        !           289:        }
        !           290:        // we select a random way to void
        !           291:        *cl=&mmu_atc_array[data][way_miss%ATC_WAYS][index];
        !           292:        way_miss++;
        !           293:        return false;
        !           294: }
        !           295: 
        !           296: /* check if an address matches a ttr */
        !           297: static inline int mmu_do_match_ttr(uae_u32 ttr, uaecptr addr, bool super)
        !           298: {
        !           299:        if (ttr & MMU_TTR_BIT_ENABLED)  {       /* TTR enabled */
        !           300:                uae_u8 msb, mask;
        !           301: 
        !           302:                msb = ((addr ^ ttr) & MMU_TTR_LOGICAL_BASE) >> 24;
        !           303:                mask = (ttr & MMU_TTR_LOGICAL_MASK) >> 16;
        !           304: 
        !           305:                if (!(msb & ~mask)) {
        !           306: 
        !           307:                        if ((ttr & MMU_TTR_BIT_SFIELD_ENABLED) == 0) {
        !           308:                                if (((ttr & MMU_TTR_BIT_SFIELD_SUPER) == 0) != (super == 0)) {
        !           309:                                        return TTR_NO_MATCH;
        !           310:                                }
        !           311:                        }
        !           312: 
        !           313:                        return (ttr & MMU_TTR_BIT_WRITE_PROTECT) ? TTR_NO_WRITE : TTR_OK_MATCH;
        !           314:                }
        !           315:        }
        !           316:        return TTR_NO_MATCH;
        !           317: }
        !           318: 
        !           319: static inline int mmu_match_ttr(uaecptr addr, bool super, bool data)
        !           320: {
        !           321:        int res;
        !           322: 
        !           323:        if (data) {
        !           324:                res = mmu_do_match_ttr(regs.dtt0, addr, super);
        !           325:                if (res == TTR_NO_MATCH)
        !           326:                        res = mmu_do_match_ttr(regs.dtt1, addr, super);
        !           327:        } else {
        !           328:                res = mmu_do_match_ttr(regs.itt0, addr, super);
        !           329:                if (res == TTR_NO_MATCH)
        !           330:                        res = mmu_do_match_ttr(regs.itt1, addr, super);
        !           331:        }
        !           332:        return res;
        !           333: }
        !           334: 
        !           335: extern uae_u16 REGPARAM3 mmu_get_word_unaligned(uaecptr addr, bool data) REGPARAM;
        !           336: extern uae_u32 REGPARAM3 mmu_get_long_unaligned(uaecptr addr, bool data) REGPARAM;
        !           337: 
        !           338: extern uae_u8 REGPARAM3 mmu_get_byte_slow(uaecptr addr, bool super, bool data,
        !           339:                                                                                  int size, struct mmu_atc_line *cl) REGPARAM;
        !           340: extern uae_u16 REGPARAM3 mmu_get_word_slow(uaecptr addr, bool super, bool data,
        !           341:                                                                                   int size, struct mmu_atc_line *cl) REGPARAM;
        !           342: extern uae_u32 REGPARAM3 mmu_get_long_slow(uaecptr addr, bool super, bool data,
        !           343:                                                                                   int size, struct mmu_atc_line *cl) REGPARAM;
        !           344: 
        !           345: extern void REGPARAM3 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, bool data) REGPARAM;
        !           346: extern void REGPARAM3 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, bool data) REGPARAM;
        !           347: 
        !           348: extern void REGPARAM3 mmu_put_byte_slow(uaecptr addr, uae_u8 val, bool super, bool data,
        !           349:                                                                                int size, struct mmu_atc_line *cl) REGPARAM;
        !           350: extern void REGPARAM3 mmu_put_word_slow(uaecptr addr, uae_u16 val, bool super, bool data,
        !           351:                                                                                int size, struct mmu_atc_line *cl) REGPARAM;
        !           352: extern void REGPARAM3 mmu_put_long_slow(uaecptr addr, uae_u32 val, bool super, bool data,
        !           353:                                                                                int size, struct mmu_atc_line *cl) REGPARAM;
        !           354: 
        !           355: extern void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode);
        !           356: 
        !           357: #define FC_DATA                (regs.s ? 5 : 1)
        !           358: #define FC_INST                (regs.s ? 6 : 2)
        !           359: 
        !           360: extern uaecptr REGPARAM3 mmu_translate(uaecptr addr, bool super, bool data, bool write) REGPARAM;
        !           361: 
        !           362: extern uae_u32 REGPARAM3 sfc_get_long(uaecptr addr) REGPARAM;
        !           363: extern uae_u16 REGPARAM3 sfc_get_word(uaecptr addr) REGPARAM;
        !           364: extern uae_u8 REGPARAM3 sfc_get_byte(uaecptr addr) REGPARAM;
        !           365: extern void REGPARAM3 dfc_put_long(uaecptr addr, uae_u32 val) REGPARAM;
        !           366: extern void REGPARAM3 dfc_put_word(uaecptr addr, uae_u16 val) REGPARAM;
        !           367: extern void REGPARAM3 dfc_put_byte(uaecptr addr, uae_u8 val) REGPARAM;
        !           368: 
        !           369: 
        !           370: extern void REGPARAM3 mmu_flush_atc(uaecptr addr, bool super, bool global) REGPARAM;
        !           371: extern void REGPARAM3 mmu_flush_atc_all(bool global) REGPARAM;
        !           372: extern void REGPARAM3 mmu_op_real(uae_u32 opcode, uae_u16 extra) REGPARAM;
        !           373: 
        !           374: extern void REGPARAM3 mmu_reset(void) REGPARAM;
        !           375: extern void REGPARAM3 mmu_set_tc(uae_u16 tc) REGPARAM;
        !           376: extern void REGPARAM3 mmu_set_super(bool super) REGPARAM;
        !           377: 
        !           378: // take care of 2 kinds of alignement, bus size and page 
        !           379: static ALWAYS_INLINE bool is_unaligned(uaecptr addr, int size)
        !           380: {
        !           381:     return unlikely((addr & (size - 1)) && (addr ^ (addr + size - 1)) & 0x1000);
        !           382: }
        !           383: 
        !           384: static ALWAYS_INLINE uaecptr mmu_get_real_address(uaecptr addr, struct mmu_atc_line *cl)
        !           385: {
        !           386:     return cl->phys | (addr & (regs.mmu_pagesize_8k?0x00001fff:0x00000fff));
        !           387: }
        !           388: 
        !           389: static ALWAYS_INLINE void phys_put_long(uaecptr addr, uae_u32 l)
        !           390: {
        !           391:     longput(addr, l);
        !           392: }
        !           393: static ALWAYS_INLINE void phys_put_word(uaecptr addr, uae_u32 w)
        !           394: {
        !           395:     wordput(addr, w);
        !           396: }
        !           397: static ALWAYS_INLINE void phys_put_byte(uaecptr addr, uae_u32 b)
        !           398: {
        !           399:     byteput(addr, b);
        !           400: }
        !           401: static ALWAYS_INLINE uae_u32 phys_get_long(uaecptr addr)
        !           402: {
        !           403:     return longget (addr);
        !           404: }
        !           405: static ALWAYS_INLINE uae_u32 phys_get_word(uaecptr addr)
        !           406: {
        !           407:     return wordget (addr);
        !           408: }
        !           409: static ALWAYS_INLINE uae_u32 phys_get_byte(uaecptr addr)
        !           410: {
        !           411:     return byteget (addr);
        !           412: }
        !           413: 
        !           414: static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, bool data, int size)
        !           415: {
        !           416:        struct mmu_atc_line *cl;
        !           417: 
        !           418:        //                                       addr,super,data
        !           419:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)!=TTR_NO_MATCH))
        !           420:                return phys_get_long(addr);
        !           421:        if (likely(mmu_lookup(addr, data, false, &cl)))
        !           422:                return phys_get_long(mmu_get_real_address(addr, cl));
        !           423:        return mmu_get_long_slow(addr, regs.s != 0, data, size, cl);
        !           424: }
        !           425: 
        !           426: static ALWAYS_INLINE uae_u16 mmu_get_word(uaecptr addr, bool data, int size)
        !           427: {
        !           428:        struct mmu_atc_line *cl;
        !           429: 
        !           430:        //                                       addr,super,data
        !           431:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)!=TTR_NO_MATCH))
        !           432:                return phys_get_word(addr);
        !           433:        if (likely(mmu_lookup(addr, data, false, &cl)))
        !           434:                return phys_get_word(mmu_get_real_address(addr, cl));
        !           435:        return mmu_get_word_slow(addr, regs.s != 0, data, size, cl);
        !           436: }
        !           437: 
        !           438: static ALWAYS_INLINE uae_u8 mmu_get_byte(uaecptr addr, bool data, int size)
        !           439: {
        !           440:        struct mmu_atc_line *cl;
        !           441: 
        !           442:        //                                       addr,super,data
        !           443:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)!=TTR_NO_MATCH))
        !           444:                return phys_get_byte(addr);
        !           445:        if (likely(mmu_lookup(addr, data, false, &cl)))
        !           446:                return phys_get_byte(mmu_get_real_address(addr, cl));
        !           447:        return mmu_get_byte_slow(addr, regs.s != 0, data, size, cl);
        !           448: }
        !           449: 
        !           450: 
        !           451: static ALWAYS_INLINE void mmu_put_long(uaecptr addr, uae_u32 val, bool data, int size)
        !           452: {
        !           453:        struct mmu_atc_line *cl;
        !           454: 
        !           455:        //                                        addr,super,data
        !           456:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)==TTR_OK_MATCH)) {
        !           457:                phys_put_long(addr,val);
        !           458:                return;
        !           459:        }
        !           460:        if (likely(mmu_lookup(addr, data, true, &cl)))
        !           461:                phys_put_long(mmu_get_real_address(addr, cl), val);
        !           462:        else
        !           463:                mmu_put_long_slow(addr, val, regs.s != 0, data, size, cl);
        !           464: }
        !           465: 
        !           466: static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, bool data, int size)
        !           467: {
        !           468:        struct mmu_atc_line *cl;
        !           469: 
        !           470:        //                                        addr,super,data
        !           471:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)==TTR_OK_MATCH)) {
        !           472:                phys_put_word(addr,val);
        !           473:                return;
        !           474:        }
        !           475:        if (likely(mmu_lookup(addr, data, true, &cl)))
        !           476:                phys_put_word(mmu_get_real_address(addr, cl), val);
        !           477:        else
        !           478:                mmu_put_word_slow(addr, val, regs.s != 0, data, size, cl);
        !           479: }
        !           480: 
        !           481: static ALWAYS_INLINE void mmu_put_byte(uaecptr addr, uae_u8 val, bool data, int size)
        !           482: {
        !           483:        struct mmu_atc_line *cl;
        !           484: 
        !           485:        //                                        addr,super,data
        !           486:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)==TTR_OK_MATCH)) {
        !           487:                phys_put_byte(addr,val);
        !           488:                return;
        !           489:        }
        !           490:        if (likely(mmu_lookup(addr, data, true, &cl)))
        !           491:                phys_put_byte(mmu_get_real_address(addr, cl), val);
        !           492:        else
        !           493:                mmu_put_byte_slow(addr, val, regs.s != 0, data, size, cl);
        !           494: }
        !           495: 
        !           496: static ALWAYS_INLINE uae_u32 mmu_get_user_long(uaecptr addr, bool super, bool data, int size)
        !           497: {
        !           498:        struct mmu_atc_line *cl;
        !           499: 
        !           500:        //                                       addr,super,data
        !           501:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)!=TTR_NO_MATCH))
        !           502:                return phys_get_long(addr);
        !           503:        if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
        !           504:                return phys_get_long(mmu_get_real_address(addr, cl));
        !           505:        return mmu_get_long_slow(addr, super, data, size, cl);
        !           506: }
        !           507: 
        !           508: static ALWAYS_INLINE uae_u16 mmu_get_user_word(uaecptr addr, bool super, bool data, int size)
        !           509: {
        !           510:        struct mmu_atc_line *cl;
        !           511: 
        !           512:        //                                       addr,super,data
        !           513:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)!=TTR_NO_MATCH))
        !           514:                return phys_get_word(addr);
        !           515:        if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
        !           516:                return phys_get_word(mmu_get_real_address(addr, cl));
        !           517:        return mmu_get_word_slow(addr, super, data, size, cl);
        !           518: }
        !           519: 
        !           520: static ALWAYS_INLINE uae_u8 mmu_get_user_byte(uaecptr addr, bool super, bool data, int size)
        !           521: {
        !           522:        struct mmu_atc_line *cl;
        !           523: 
        !           524:        //                                       addr,super,data
        !           525:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)!=TTR_NO_MATCH))
        !           526:                return phys_get_byte(addr);
        !           527:        if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
        !           528:                return phys_get_byte(mmu_get_real_address(addr, cl));
        !           529:        return mmu_get_byte_slow(addr, super, data, size, cl);
        !           530: }
        !           531: 
        !           532: static ALWAYS_INLINE void mmu_put_user_long(uaecptr addr, uae_u32 val, bool super, bool data, int size)
        !           533: {
        !           534:        struct mmu_atc_line *cl;
        !           535: 
        !           536:        //                                        addr,super,data
        !           537:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)==TTR_OK_MATCH)) {
        !           538:                phys_put_long(addr,val);
        !           539:                return;
        !           540:        }
        !           541:        if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
        !           542:                phys_put_long(mmu_get_real_address(addr, cl), val);
        !           543:        else
        !           544:                mmu_put_long_slow(addr, val, super, data, size, cl);
        !           545: }
        !           546: 
        !           547: static ALWAYS_INLINE void mmu_put_user_word(uaecptr addr, uae_u16 val, bool super, bool data, int size)
        !           548: {
        !           549:        struct mmu_atc_line *cl;
        !           550: 
        !           551:        //                                        addr,super,data
        !           552:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)==TTR_OK_MATCH)) {
        !           553:                phys_put_word(addr,val);
        !           554:                return;
        !           555:        }
        !           556:        if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
        !           557:                phys_put_word(mmu_get_real_address(addr, cl), val);
        !           558:        else
        !           559:                mmu_put_word_slow(addr, val, super, data, size, cl);
        !           560: }
        !           561: 
        !           562: static ALWAYS_INLINE void mmu_put_user_byte(uaecptr addr, uae_u8 val, bool super, bool data, int size)
        !           563: {
        !           564:        struct mmu_atc_line *cl;
        !           565: 
        !           566:        //                                        addr,super,data
        !           567:        if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)==TTR_OK_MATCH)) {
        !           568:                phys_put_byte(addr,val);
        !           569:                return;
        !           570:        }
        !           571:        if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
        !           572:                phys_put_byte(mmu_get_real_address(addr, cl), val);
        !           573:        else
        !           574:                mmu_put_byte_slow(addr, val, super, data, size, cl);
        !           575: }
        !           576: 
        !           577: 
        !           578: static ALWAYS_INLINE void HWput_l(uaecptr addr, uae_u32 l)
        !           579: {
        !           580:     put_long (addr, l);
        !           581: }
        !           582: static ALWAYS_INLINE void HWput_w(uaecptr addr, uae_u32 w)
        !           583: {
        !           584:     put_word (addr, w);
        !           585: }
        !           586: static ALWAYS_INLINE void HWput_b(uaecptr addr, uae_u32 b)
        !           587: {
        !           588:     put_byte (addr, b);
        !           589: }
        !           590: static ALWAYS_INLINE uae_u32 HWget_l(uaecptr addr)
        !           591: {
        !           592:     return get_long (addr);
        !           593: }
        !           594: static ALWAYS_INLINE uae_u32 HWget_w(uaecptr addr)
        !           595: {
        !           596:     return get_word (addr);
        !           597: }
        !           598: static ALWAYS_INLINE uae_u32 HWget_b(uaecptr addr)
        !           599: {
        !           600:     return get_byte (addr);
        !           601: }
        !           602: 
        !           603: static ALWAYS_INLINE uae_u32 uae_mmu_get_ilong(uaecptr addr)
        !           604: {
        !           605:        if (unlikely(is_unaligned(addr, 4)))
        !           606:                return mmu_get_long_unaligned(addr, false);
        !           607:        return mmu_get_long(addr, false, sz_long);
        !           608: }
        !           609: static ALWAYS_INLINE uae_u16 uae_mmu_get_iword(uaecptr addr)
        !           610: {
        !           611:        if (unlikely(is_unaligned(addr, 2)))
        !           612:                return mmu_get_word_unaligned(addr, false);
        !           613:        return mmu_get_word(addr, false, sz_word);
        !           614: }
        !           615: static ALWAYS_INLINE uae_u16 uae_mmu_get_ibyte(uaecptr addr)
        !           616: {
        !           617:        return mmu_get_byte(addr, false, sz_byte);
        !           618: }
        !           619: static ALWAYS_INLINE uae_u32 uae_mmu_get_long(uaecptr addr)
        !           620: {
        !           621:        if (unlikely(is_unaligned(addr, 4)))
        !           622:                return mmu_get_long_unaligned(addr, true);
        !           623:        return mmu_get_long(addr, true, sz_long);
        !           624: }
        !           625: static ALWAYS_INLINE uae_u16 uae_mmu_get_word(uaecptr addr)
        !           626: {
        !           627:        if (unlikely(is_unaligned(addr, 2)))
        !           628:                return mmu_get_word_unaligned(addr, true);
        !           629:        return mmu_get_word(addr, true, sz_word);
        !           630: }
        !           631: static ALWAYS_INLINE uae_u8 uae_mmu_get_byte(uaecptr addr)
        !           632: {
        !           633:        return mmu_get_byte(addr, true, sz_byte);
        !           634: }
        !           635: static ALWAYS_INLINE void uae_mmu_put_long(uaecptr addr, uae_u32 val)
        !           636: {
        !           637:        if (unlikely(is_unaligned(addr, 4)))
        !           638:                mmu_put_long_unaligned(addr, val, true);
        !           639:        else
        !           640:                mmu_put_long(addr, val, true, sz_long);
        !           641: }
        !           642: static ALWAYS_INLINE void uae_mmu_put_word(uaecptr addr, uae_u16 val)
        !           643: {
        !           644:        if (unlikely(is_unaligned(addr, 2)))
        !           645:                mmu_put_word_unaligned(addr, val, true);
        !           646:        else
        !           647:                mmu_put_word(addr, val, true, sz_word);
        !           648: }
        !           649: static ALWAYS_INLINE void uae_mmu_put_byte(uaecptr addr, uae_u8 val)
        !           650: {
        !           651:        mmu_put_byte(addr, val, true, sz_byte);
        !           652: }
        !           653: 
        !           654: STATIC_INLINE void put_byte_mmu (uaecptr addr, uae_u32 v)
        !           655: {
        !           656:     uae_mmu_put_byte (addr, v);
        !           657: }
        !           658: STATIC_INLINE void put_word_mmu (uaecptr addr, uae_u32 v)
        !           659: {
        !           660:     uae_mmu_put_word (addr, v);
        !           661: }
        !           662: STATIC_INLINE void put_long_mmu (uaecptr addr, uae_u32 v)
        !           663: {
        !           664:     uae_mmu_put_long (addr, v);
        !           665: }
        !           666: STATIC_INLINE uae_u32 get_byte_mmu (uaecptr addr)
        !           667: {
        !           668:     return uae_mmu_get_byte (addr);
        !           669: }
        !           670: STATIC_INLINE uae_u32 get_word_mmu (uaecptr addr)
        !           671: {
        !           672:     return uae_mmu_get_word (addr);
        !           673: }
        !           674: STATIC_INLINE uae_u32 get_long_mmu (uaecptr addr)
        !           675: {
        !           676:     return uae_mmu_get_long (addr);
        !           677: }
        !           678: STATIC_INLINE uae_u32 get_ibyte_mmu (int o)
        !           679: {
        !           680:     uae_u32 pc = m68k_getpc () + o;
        !           681:     return uae_mmu_get_iword (pc);
        !           682: }
        !           683: STATIC_INLINE uae_u32 get_iword_mmu (int o)
        !           684: {
        !           685:     uae_u32 pc = m68k_getpc () + o;
        !           686:     return uae_mmu_get_iword (pc);
        !           687: }
        !           688: STATIC_INLINE uae_u32 get_ilong_mmu (int o)
        !           689: {
        !           690:     uae_u32 pc = m68k_getpc () + o;
        !           691:     return uae_mmu_get_ilong (pc);
        !           692: }
        !           693: STATIC_INLINE uae_u32 next_iword_mmu (void)
        !           694: {
        !           695:     uae_u32 pc = m68k_getpc ();
        !           696:     m68k_incpci (2);
        !           697:     return uae_mmu_get_iword (pc);
        !           698: }
        !           699: STATIC_INLINE uae_u32 next_ilong_mmu (void)
        !           700: {
        !           701:     uae_u32 pc = m68k_getpc ();
        !           702:     m68k_incpci (4);
        !           703:     return uae_mmu_get_ilong (pc);
        !           704: }
        !           705: 
        !           706: extern void m68k_do_rts_mmu (void);
        !           707: extern void m68k_do_rte_mmu (uaecptr a7);
        !           708: extern void m68k_do_bsr_mmu (uaecptr oldpc, uae_s32 offset);
        !           709: 
        !           710: struct mmufixup
        !           711: {
        !           712:     int reg;
        !           713:     uae_u32 value;
        !           714: };
        !           715: extern struct mmufixup mmufixup[2];
        !           716: 
        !           717: #endif /* CPUMMU_H */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.