Annotation of hatari/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__);
        !            64: #define ENDTRY    __poptry();}
        !            65: #define THROW(x) if (__is_catched()) {fprintf(stderr,"Longjumping %s in %d\n",__FILE__,__LINE__);longjmp(__exbuf,x);}
        !            66: #define THROW_AGAIN(var) if (__is_catched()) longjmp(*__poptry(),__exvalue)
        !            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:        uae_u16 tag;
        !           211:        unsigned tt : 1;
        !           212:        unsigned valid_data : 1;
        !           213:        unsigned valid_inst : 1;
        !           214:        unsigned global : 1;
        !           215:        unsigned modified : 1;
        !           216:        unsigned write_protect : 1;
        !           217:        unsigned hw : 1;
        !           218:        unsigned bus_fault : 1;
        !           219:        uaecptr phys;
        !           220: };
        !           221: 
        !           222: /*
        !           223:  * We don't need to store the whole logical address in the atc cache, as part of
        !           224:  * it is encoded as index into the cache. 14 bits of the address are stored in
        !           225:  * the tag, this means at least 6 bits must go into the index. The upper two
        !           226:  * bits of the tag define the type of data in the atc line:
        !           227:  * - 00: a normal memory address
        !           228:  * - 11: invalid memory address or hardware access
        !           229:  *       (generated via ~ATC_TAG(addr) in the slow path)
        !           230:  * - 10: empty atc line
        !           231:  */
        !           232: 
        !           233: #define ATC_TAG_SHIFT          18
        !           234: #define ATC_TAG(addr)          ((uae_u32)(addr) >> ATC_TAG_SHIFT)
        !           235: 
        !           236: 
        !           237: #define ATC_L1_SIZE_LOG                8
        !           238: #define ATC_L1_SIZE                    (1 << ATC_L1_SIZE_LOG)
        !           239: 
        !           240: #define ATC_L1_INDEX(addr)     (((addr) >> 12) % ATC_L1_SIZE)
        !           241: 
        !           242: /*
        !           243:  * first level atc cache
        !           244:  * indexed by [super][data][rw][idx]
        !           245:  */
        !           246: 
        !           247: typedef struct mmu_atc_line mmu_atc_l1_array[2][2][ATC_L1_SIZE];
        !           248: extern mmu_atc_l1_array atc_l1[2];
        !           249: extern mmu_atc_l1_array *current_atc;
        !           250: 
        !           251: #define ATC_L2_SIZE_LOG                12
        !           252: #define ATC_L2_SIZE                    (1 << ATC_L2_SIZE_LOG)
        !           253: 
        !           254: #define ATC_L2_INDEX(addr)     ((((addr) >> 12) ^ ((addr) >> (32 - ATC_L2_SIZE_LOG))) % ATC_L2_SIZE)
        !           255: 
        !           256: extern struct mmu_atc_line atc_l2[2][ATC_L2_SIZE];
        !           257: 
        !           258: /*
        !           259:  * lookup address in the level 1 atc cache,
        !           260:  * the data and write arguments are constant in the common,
        !           261:  * thus allows gcc to generate a constant offset.
        !           262:  */
        !           263: static ALWAYS_INLINE bool mmu_lookup(uaecptr addr, bool data, bool write,
        !           264:                                                                          struct mmu_atc_line **cl)
        !           265: {
        !           266:        addr >>= 12;
        !           267:        *cl = &(*current_atc)[data ? 1 : 0][write ? 1 : 0][addr % ATC_L1_SIZE];
        !           268:        return (*cl)->tag == addr >> (ATC_TAG_SHIFT - 12);
        !           269: }
        !           270: 
        !           271: /*
        !           272:  * similiar to mmu_user_lookup, but for the use of the moves instruction
        !           273:  */
        !           274: static ALWAYS_INLINE bool mmu_user_lookup(uaecptr addr, bool super, bool data,
        !           275:                                                                                   bool write, struct mmu_atc_line **cl)
        !           276: {
        !           277:        addr >>= 12;
        !           278:        *cl = &atc_l1[super ? 1 : 0][data ? 1 : 0][write ? 1 : 0][addr % ATC_L1_SIZE];
        !           279:        return (*cl)->tag == addr >> (ATC_TAG_SHIFT - 12);
        !           280: }
        !           281: 
        !           282: extern uae_u16 REGPARAM3 mmu_get_word_unaligned(uaecptr addr, bool data) REGPARAM;
        !           283: extern uae_u32 REGPARAM3 mmu_get_long_unaligned(uaecptr addr, bool data) REGPARAM;
        !           284: 
        !           285: extern uae_u8 REGPARAM3 mmu_get_byte_slow(uaecptr addr, bool super, bool data,
        !           286:                                                                                  int size, struct mmu_atc_line *cl) REGPARAM;
        !           287: extern uae_u16 REGPARAM3 mmu_get_word_slow(uaecptr addr, bool super, bool data,
        !           288:                                                                                   int size, struct mmu_atc_line *cl) REGPARAM;
        !           289: extern uae_u32 REGPARAM3 mmu_get_long_slow(uaecptr addr, bool super, bool data,
        !           290:                                                                                   int size, struct mmu_atc_line *cl) REGPARAM;
        !           291: 
        !           292: extern void REGPARAM3 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, bool data) REGPARAM;
        !           293: extern void REGPARAM3 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, bool data) REGPARAM;
        !           294: 
        !           295: extern void REGPARAM3 mmu_put_byte_slow(uaecptr addr, uae_u8 val, bool super, bool data,
        !           296:                                                                                int size, struct mmu_atc_line *cl) REGPARAM;
        !           297: extern void REGPARAM3 mmu_put_word_slow(uaecptr addr, uae_u16 val, bool super, bool data,
        !           298:                                                                                int size, struct mmu_atc_line *cl) REGPARAM;
        !           299: extern void REGPARAM3 mmu_put_long_slow(uaecptr addr, uae_u32 val, bool super, bool data,
        !           300:                                                                                int size, struct mmu_atc_line *cl) REGPARAM;
        !           301: 
        !           302: extern void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode);
        !           303: 
        !           304: #define FC_DATA                (regs.s ? 5 : 1)
        !           305: #define FC_INST                (regs.s ? 6 : 2)
        !           306: 
        !           307: extern uaecptr REGPARAM3 mmu_translate(uaecptr addr, bool super, bool data, bool write) REGPARAM;
        !           308: 
        !           309: extern uae_u32 REGPARAM3 sfc_get_long(uaecptr addr) REGPARAM;
        !           310: extern uae_u16 REGPARAM3 sfc_get_word(uaecptr addr) REGPARAM;
        !           311: extern uae_u8 REGPARAM3 sfc_get_byte(uaecptr addr) REGPARAM;
        !           312: extern void REGPARAM3 dfc_put_long(uaecptr addr, uae_u32 val) REGPARAM;
        !           313: extern void REGPARAM3 dfc_put_word(uaecptr addr, uae_u16 val) REGPARAM;
        !           314: extern void REGPARAM3 dfc_put_byte(uaecptr addr, uae_u8 val) REGPARAM;
        !           315: 
        !           316: 
        !           317: extern void REGPARAM3 mmu_flush_atc(uaecptr addr, bool super, bool global) REGPARAM;
        !           318: extern void REGPARAM3 mmu_flush_atc_all(bool global) REGPARAM;
        !           319: extern void REGPARAM3 mmu_op_real(uae_u32 opcode, uae_u16 extra) REGPARAM;
        !           320: 
        !           321: extern void REGPARAM3 mmu_reset(void) REGPARAM;
        !           322: extern void REGPARAM3 mmu_set_tc(uae_u16 tc) REGPARAM;
        !           323: extern void REGPARAM3 mmu_set_super(bool super) REGPARAM;
        !           324: 
        !           325: static ALWAYS_INLINE bool is_unaligned(uaecptr addr, int size)
        !           326: {
        !           327:     return unlikely((addr & (size - 1)) && (addr ^ (addr + size - 1)) & 0x1000);
        !           328: }
        !           329: 
        !           330: static ALWAYS_INLINE uaecptr mmu_get_real_address(uaecptr addr, struct mmu_atc_line *cl)
        !           331: {
        !           332:     return cl->phys + addr;
        !           333: }
        !           334: 
        !           335: static ALWAYS_INLINE void phys_put_long(uaecptr addr, uae_u32 l)
        !           336: {
        !           337:     longput(addr, l);
        !           338: }
        !           339: static ALWAYS_INLINE void phys_put_word(uaecptr addr, uae_u32 w)
        !           340: {
        !           341:     wordput(addr, w);
        !           342: }
        !           343: static ALWAYS_INLINE void phys_put_byte(uaecptr addr, uae_u32 b)
        !           344: {
        !           345:     byteput(addr, b);
        !           346: }
        !           347: static ALWAYS_INLINE uae_u32 phys_get_long(uaecptr addr)
        !           348: {
        !           349:     return longget (addr);
        !           350: }
        !           351: static ALWAYS_INLINE uae_u32 phys_get_word(uaecptr addr)
        !           352: {
        !           353:     return wordget (addr);
        !           354: }
        !           355: static ALWAYS_INLINE uae_u32 phys_get_byte(uaecptr addr)
        !           356: {
        !           357:     return byteget (addr);
        !           358: }
        !           359: 
        !           360: static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, bool data, int size)
        !           361: {
        !           362:        struct mmu_atc_line *cl;
        !           363: 
        !           364:        if (likely(mmu_lookup(addr, data, false, &cl)))
        !           365:                return phys_get_long(mmu_get_real_address(addr, cl));
        !           366:        return mmu_get_long_slow(addr, regs.s != 0, data, size, cl);
        !           367: }
        !           368: 
        !           369: static ALWAYS_INLINE uae_u16 mmu_get_word(uaecptr addr, bool data, int size)
        !           370: {
        !           371:        struct mmu_atc_line *cl;
        !           372: 
        !           373:        if (likely(mmu_lookup(addr, data, false, &cl)))
        !           374:                return phys_get_word(mmu_get_real_address(addr, cl));
        !           375:        return mmu_get_word_slow(addr, regs.s != 0, data, size, cl);
        !           376: }
        !           377: 
        !           378: static ALWAYS_INLINE uae_u8 mmu_get_byte(uaecptr addr, bool data, int size)
        !           379: {
        !           380:        struct mmu_atc_line *cl;
        !           381: 
        !           382:        if (likely(mmu_lookup(addr, data, false, &cl)))
        !           383:                return phys_get_byte(mmu_get_real_address(addr, cl));
        !           384:        return mmu_get_byte_slow(addr, regs.s != 0, data, size, cl);
        !           385: }
        !           386: 
        !           387: 
        !           388: static ALWAYS_INLINE void mmu_put_long(uaecptr addr, uae_u32 val, bool data, int size)
        !           389: {
        !           390:        struct mmu_atc_line *cl;
        !           391: 
        !           392:        if (likely(mmu_lookup(addr, data, true, &cl)))
        !           393:                phys_put_long(mmu_get_real_address(addr, cl), val);
        !           394:        else
        !           395:                mmu_put_long_slow(addr, val, regs.s != 0, data, size, cl);
        !           396: }
        !           397: 
        !           398: static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, bool data, int size)
        !           399: {
        !           400:        struct mmu_atc_line *cl;
        !           401: 
        !           402:        if (likely(mmu_lookup(addr, data, true, &cl)))
        !           403:                phys_put_word(mmu_get_real_address(addr, cl), val);
        !           404:        else
        !           405:                mmu_put_word_slow(addr, val, regs.s != 0, data, size, cl);
        !           406: }
        !           407: 
        !           408: static ALWAYS_INLINE void mmu_put_byte(uaecptr addr, uae_u8 val, bool data, int size)
        !           409: {
        !           410:        struct mmu_atc_line *cl;
        !           411: 
        !           412:        if (likely(mmu_lookup(addr, data, true, &cl)))
        !           413:                phys_put_byte(mmu_get_real_address(addr, cl), val);
        !           414:        else
        !           415:                mmu_put_byte_slow(addr, val, regs.s != 0, data, size, cl);
        !           416: }
        !           417: 
        !           418: static ALWAYS_INLINE uae_u32 mmu_get_user_long(uaecptr addr, bool super, bool data, int size)
        !           419: {
        !           420:        struct mmu_atc_line *cl;
        !           421: 
        !           422:        if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
        !           423:                return phys_get_long(mmu_get_real_address(addr, cl));
        !           424:        return mmu_get_long_slow(addr, super, data, size, cl);
        !           425: }
        !           426: 
        !           427: static ALWAYS_INLINE uae_u16 mmu_get_user_word(uaecptr addr, bool super, bool data, int size)
        !           428: {
        !           429:        struct mmu_atc_line *cl;
        !           430: 
        !           431:        if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
        !           432:                return phys_get_word(mmu_get_real_address(addr, cl));
        !           433:        return mmu_get_word_slow(addr, super, data, size, cl);
        !           434: }
        !           435: 
        !           436: static ALWAYS_INLINE uae_u8 mmu_get_user_byte(uaecptr addr, bool super, bool data, int size)
        !           437: {
        !           438:        struct mmu_atc_line *cl;
        !           439: 
        !           440:        if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
        !           441:                return phys_get_byte(mmu_get_real_address(addr, cl));
        !           442:        return mmu_get_byte_slow(addr, super, data, size, cl);
        !           443: }
        !           444: 
        !           445: static ALWAYS_INLINE void mmu_put_user_long(uaecptr addr, uae_u32 val, bool super, bool data, int size)
        !           446: {
        !           447:        struct mmu_atc_line *cl;
        !           448: 
        !           449:        if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
        !           450:                phys_put_long(mmu_get_real_address(addr, cl), val);
        !           451:        else
        !           452:                mmu_put_long_slow(addr, val, super, data, size, cl);
        !           453: }
        !           454: 
        !           455: static ALWAYS_INLINE void mmu_put_user_word(uaecptr addr, uae_u16 val, bool super, bool data, int size)
        !           456: {
        !           457:        struct mmu_atc_line *cl;
        !           458: 
        !           459:        if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
        !           460:                phys_put_word(mmu_get_real_address(addr, cl), val);
        !           461:        else
        !           462:                mmu_put_word_slow(addr, val, super, data, size, cl);
        !           463: }
        !           464: 
        !           465: static ALWAYS_INLINE void mmu_put_user_byte(uaecptr addr, uae_u8 val, bool super, bool data, int size)
        !           466: {
        !           467:        struct mmu_atc_line *cl;
        !           468: 
        !           469:        if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
        !           470:                phys_put_byte(mmu_get_real_address(addr, cl), val);
        !           471:        else
        !           472:                mmu_put_byte_slow(addr, val, super, data, size, cl);
        !           473: }
        !           474: 
        !           475: 
        !           476: static ALWAYS_INLINE void HWput_l(uaecptr addr, uae_u32 l)
        !           477: {
        !           478:     put_long (addr, l);
        !           479: }
        !           480: static ALWAYS_INLINE void HWput_w(uaecptr addr, uae_u32 w)
        !           481: {
        !           482:     put_word (addr, w);
        !           483: }
        !           484: static ALWAYS_INLINE void HWput_b(uaecptr addr, uae_u32 b)
        !           485: {
        !           486:     put_byte (addr, b);
        !           487: }
        !           488: static ALWAYS_INLINE uae_u32 HWget_l(uaecptr addr)
        !           489: {
        !           490:     return get_long (addr);
        !           491: }
        !           492: static ALWAYS_INLINE uae_u32 HWget_w(uaecptr addr)
        !           493: {
        !           494:     return get_word (addr);
        !           495: }
        !           496: static ALWAYS_INLINE uae_u32 HWget_b(uaecptr addr)
        !           497: {
        !           498:     return get_byte (addr);
        !           499: }
        !           500: 
        !           501: static ALWAYS_INLINE uae_u32 uae_mmu_get_ilong(uaecptr addr)
        !           502: {
        !           503:        if (unlikely(is_unaligned(addr, 4)))
        !           504:                return mmu_get_long_unaligned(addr, false);
        !           505:        return mmu_get_long(addr, false, sz_long);
        !           506: }
        !           507: static ALWAYS_INLINE uae_u16 uae_mmu_get_iword(uaecptr addr)
        !           508: {
        !           509:        if (unlikely(is_unaligned(addr, 2)))
        !           510:                return mmu_get_word_unaligned(addr, false);
        !           511:        return mmu_get_word(addr, false, sz_word);
        !           512: }
        !           513: static ALWAYS_INLINE uae_u16 uae_mmu_get_ibyte(uaecptr addr)
        !           514: {
        !           515:        return mmu_get_byte(addr, false, sz_byte);
        !           516: }
        !           517: static ALWAYS_INLINE uae_u32 uae_mmu_get_long(uaecptr addr)
        !           518: {
        !           519:        if (unlikely(is_unaligned(addr, 4)))
        !           520:                return mmu_get_long_unaligned(addr, true);
        !           521:        return mmu_get_long(addr, true, sz_long);
        !           522: }
        !           523: static ALWAYS_INLINE uae_u16 uae_mmu_get_word(uaecptr addr)
        !           524: {
        !           525:        if (unlikely(is_unaligned(addr, 2)))
        !           526:                return mmu_get_word_unaligned(addr, true);
        !           527:        return mmu_get_word(addr, true, sz_word);
        !           528: }
        !           529: static ALWAYS_INLINE uae_u8 uae_mmu_get_byte(uaecptr addr)
        !           530: {
        !           531:        return mmu_get_byte(addr, true, sz_byte);
        !           532: }
        !           533: static ALWAYS_INLINE void uae_mmu_put_long(uaecptr addr, uae_u32 val)
        !           534: {
        !           535:        if (unlikely(is_unaligned(addr, 4)))
        !           536:                mmu_put_long_unaligned(addr, val, true);
        !           537:        else
        !           538:                mmu_put_long(addr, val, true, sz_long);
        !           539: }
        !           540: static ALWAYS_INLINE void uae_mmu_put_word(uaecptr addr, uae_u16 val)
        !           541: {
        !           542:        if (unlikely(is_unaligned(addr, 2)))
        !           543:                mmu_put_word_unaligned(addr, val, true);
        !           544:        else
        !           545:                mmu_put_word(addr, val, true, sz_word);
        !           546: }
        !           547: static ALWAYS_INLINE void uae_mmu_put_byte(uaecptr addr, uae_u8 val)
        !           548: {
        !           549:        mmu_put_byte(addr, val, true, sz_byte);
        !           550: }
        !           551: 
        !           552: STATIC_INLINE void put_byte_mmu (uaecptr addr, uae_u32 v)
        !           553: {
        !           554:     uae_mmu_put_byte (addr, v);
        !           555: }
        !           556: STATIC_INLINE void put_word_mmu (uaecptr addr, uae_u32 v)
        !           557: {
        !           558:     uae_mmu_put_word (addr, v);
        !           559: }
        !           560: STATIC_INLINE void put_long_mmu (uaecptr addr, uae_u32 v)
        !           561: {
        !           562:     uae_mmu_put_long (addr, v);
        !           563: }
        !           564: STATIC_INLINE uae_u32 get_byte_mmu (uaecptr addr)
        !           565: {
        !           566:     return uae_mmu_get_byte (addr);
        !           567: }
        !           568: STATIC_INLINE uae_u32 get_word_mmu (uaecptr addr)
        !           569: {
        !           570:     return uae_mmu_get_word (addr);
        !           571: }
        !           572: STATIC_INLINE uae_u32 get_long_mmu (uaecptr addr)
        !           573: {
        !           574:     return uae_mmu_get_long (addr);
        !           575: }
        !           576: STATIC_INLINE uae_u32 get_ibyte_mmu (int o)
        !           577: {
        !           578:     uae_u32 pc = m68k_getpc () + o;
        !           579:     return uae_mmu_get_iword (pc);
        !           580: }
        !           581: STATIC_INLINE uae_u32 get_iword_mmu (int o)
        !           582: {
        !           583:     uae_u32 pc = m68k_getpc () + o;
        !           584:     return uae_mmu_get_iword (pc);
        !           585: }
        !           586: STATIC_INLINE uae_u32 get_ilong_mmu (int o)
        !           587: {
        !           588:     uae_u32 pc = m68k_getpc () + o;
        !           589:     return uae_mmu_get_ilong (pc);
        !           590: }
        !           591: STATIC_INLINE uae_u32 next_iword_mmu (void)
        !           592: {
        !           593:     uae_u32 pc = m68k_getpc ();
        !           594:     m68k_incpci (2);
        !           595:     return uae_mmu_get_iword (pc);
        !           596: }
        !           597: STATIC_INLINE uae_u32 next_ilong_mmu (void)
        !           598: {
        !           599:     uae_u32 pc = m68k_getpc ();
        !           600:     m68k_incpci (4);
        !           601:     return uae_mmu_get_ilong (pc);
        !           602: }
        !           603: 
        !           604: extern void m68k_do_rts_mmu (void);
        !           605: extern void m68k_do_rte_mmu (uaecptr a7);
        !           606: extern void m68k_do_bsr_mmu (uaecptr oldpc, uae_s32 offset);
        !           607: 
        !           608: struct mmufixup
        !           609: {
        !           610:     int reg;
        !           611:     uae_u32 value;
        !           612: };
        !           613: extern struct mmufixup mmufixup[2];
        !           614: 
        !           615: #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.