Annotation of qemu/roms/openbios/arch/ppc/ofmem.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *   Creation Date: <1999/11/07 19:02:11 samuel>
        !             3:  *   Time-stamp: <2004/01/07 19:42:36 samuel>
        !             4:  *
        !             5:  *     <ofmem.c>
        !             6:  *
        !             7:  *     OF Memory manager
        !             8:  *
        !             9:  *   Copyright (C) 1999-2004 Samuel Rydh ([email protected])
        !            10:  *   Copyright (C) 2004 Stefan Reinauer
        !            11:  *
        !            12:  *   This program is free software; you can redistribute it and/or
        !            13:  *   modify it under the terms of the GNU General Public License
        !            14:  *   as published by the Free Software Foundation
        !            15:  *
        !            16:  */
        !            17: 
        !            18: /* TODO: Clean up MOLisms in a decent way */
        !            19: 
        !            20: #include "config.h"
        !            21: #include "libopenbios/bindings.h"
        !            22: #include "libc/string.h"
        !            23: #include "libopenbios/ofmem.h"
        !            24: #include "kernel.h"
        !            25: #ifdef I_WANT_MOLISMS
        !            26: #include "mol/prom.h"
        !            27: #include "mol/mol.h"
        !            28: #endif
        !            29: #include "mmutypes.h"
        !            30: #include "asm/processor.h"
        !            31: #ifdef I_WANT_MOLISMS
        !            32: #include "osi_calls.h"
        !            33: #endif
        !            34: 
        !            35: #define BIT(n)         (1U<<(31-(n)))
        !            36: 
        !            37: /* called from assembly */
        !            38: extern void    dsi_exception( void );
        !            39: extern void    isi_exception( void );
        !            40: extern void    setup_mmu( unsigned long code_base, unsigned long code_size, unsigned long ramsize );
        !            41: 
        !            42: /****************************************************************
        !            43:  * Memory usage (before of_quiesce is called)
        !            44:  *
        !            45:  *                     Physical
        !            46:  *
        !            47:  *     0x00000000      Exception vectors
        !            48:  *     0x00004000      Free space
        !            49:  *     0x01e00000      Open Firmware (us)
        !            50:  *     0x01f00000      OF allocations
        !            51:  *     0x01ff0000      PTE Hash
        !            52:  *     0x02000000-     Free space
        !            53:  *
        !            54:  * Allocations grow downwards from 0x01e00000
        !            55:  *
        !            56:  ****************************************************************/
        !            57: 
        !            58: #define HASH_SIZE              (2 << 15)
        !            59: #define SEGR_BASE              0x400           /* segment number range to use */
        !            60: 
        !            61: #define FREE_BASE_1            0x00004000
        !            62: #define OF_CODE_START          0x01e00000
        !            63: /* #define OF_MALLOC_BASE      0x01f00000 */
        !            64: extern char _end[];
        !            65: #define OF_MALLOC_BASE         _end
        !            66: 
        !            67: #define HASH_BASE              (0x02000000 - HASH_SIZE)
        !            68: #define FREE_BASE_2            0x02000000
        !            69: 
        !            70: #define RAMSIZE                        0x02000000      /* XXXXXXXXXXXXXXXXXXX FIXME XXXXXXXXXXXXXXX */
        !            71: 
        !            72: static ofmem_t s_ofmem;
        !            73: 
        !            74: #define IO_BASE                        0x80000000
        !            75: #define OFMEM (&s_ofmem)
        !            76: 
        !            77: static inline unsigned long
        !            78: get_hash_base( void )
        !            79: {
        !            80:        return HASH_BASE;
        !            81: }
        !            82: 
        !            83: static inline unsigned long
        !            84: get_hash_size( void )
        !            85: {
        !            86:        return HASH_SIZE;
        !            87: }
        !            88: 
        !            89: static ucell get_heap_top( void )
        !            90: {
        !            91:        return HASH_BASE;
        !            92: }
        !            93: 
        !            94: static inline size_t ALIGN_SIZE(size_t x, size_t a)
        !            95: {
        !            96:     return (x + a - 1) & ~(a-1);
        !            97: }
        !            98: 
        !            99: ofmem_t* ofmem_arch_get_private(void)
        !           100: {
        !           101:        return OFMEM;
        !           102: }
        !           103: 
        !           104: void* ofmem_arch_get_malloc_base(void)
        !           105: {
        !           106:        return OF_MALLOC_BASE;
        !           107: }
        !           108: 
        !           109: ucell ofmem_arch_get_heap_top(void)
        !           110: {
        !           111:        return get_heap_top();
        !           112: }
        !           113: 
        !           114: ucell ofmem_arch_get_virt_top(void)
        !           115: {
        !           116:        return IO_BASE;
        !           117: }
        !           118: 
        !           119: void ofmem_arch_unmap_pages(ucell virt, ucell size)
        !           120: {
        !           121:        /* kill page mappings in provided range */
        !           122: }
        !           123: 
        !           124: void ofmem_arch_early_map_pages(ucell phys, ucell virt, ucell size, ucell mode)
        !           125: {
        !           126:        /* none yet */
        !           127: }
        !           128: 
        !           129: /************************************************************************/
        !           130: /*     OF private allocations                                          */
        !           131: /************************************************************************/
        !           132: 
        !           133: void *
        !           134: malloc( int size )
        !           135: {
        !           136:        return ofmem_malloc(size);
        !           137: }
        !           138: 
        !           139: void
        !           140: free( void *ptr )
        !           141: {
        !           142:        return ofmem_free(ptr);
        !           143: }
        !           144: 
        !           145: void *
        !           146: realloc( void *ptr, size_t size )
        !           147: {
        !           148:        return ofmem_realloc(ptr, size);
        !           149: }
        !           150: 
        !           151: 
        !           152: /************************************************************************/
        !           153: /*     misc                                                            */
        !           154: /************************************************************************/
        !           155: 
        !           156: ucell ofmem_arch_default_translation_mode( ucell phys )
        !           157: {
        !           158:        /* XXX: Guard bit not set as it should! */
        !           159:        if( phys < IO_BASE || phys >= 0xffc00000 )
        !           160:                return 0x02;    /*0xa*/ /* wim GxPp */
        !           161:        return 0x6a;            /* WIm GxPp, I/O */
        !           162: }
        !           163: 
        !           164: 
        !           165: /************************************************************************/
        !           166: /*     page fault handler                                              */
        !           167: /************************************************************************/
        !           168: 
        !           169: static ucell
        !           170: ea_to_phys( ucell ea, ucell *mode )
        !           171: {
        !           172:        ucell phys;
        !           173: 
        !           174:        /* hardcode our translation needs */
        !           175:        if( ea >= OF_CODE_START && ea < FREE_BASE_2 ) {
        !           176:                *mode = ofmem_arch_default_translation_mode( ea );
        !           177:                return ea;
        !           178:        }
        !           179: 
        !           180:        phys = ofmem_translate(ea, mode);
        !           181:        if( phys == (ucell)-1 ) {
        !           182: #ifdef I_WANT_MOLISMS
        !           183:                if( ea != 0x80816c00 )
        !           184:                        printk("ea_to_phys: no translation for %08lx, using 1-1\n", ea );
        !           185: #endif
        !           186:                phys = ea;
        !           187:                *mode = ofmem_arch_default_translation_mode( phys );
        !           188: 
        !           189: #ifdef I_WANT_MOLISMS
        !           190:                forth_segv_handler( (char*)ea );
        !           191:                OSI_Debugger(1);
        !           192: #endif
        !           193:                /* print_virt_range(); */
        !           194:                /* print_phys_range(); */
        !           195:                /* print_trans(); */
        !           196:        }
        !           197:        return phys;
        !           198: }
        !           199: 
        !           200: static void
        !           201: hash_page( ucell ea, ucell phys, ucell mode )
        !           202: {
        !           203:        static int next_grab_slot=0;
        !           204:        unsigned long *upte, cmp, hash1;
        !           205:        int i, vsid, found;
        !           206:        mPTE_t *pp;
        !           207: 
        !           208:        vsid = (ea>>28) + SEGR_BASE;
        !           209:        cmp = BIT(0) | (vsid << 7) | ((ea & 0x0fffffff) >> 22);
        !           210: 
        !           211:        hash1 = vsid;
        !           212:        hash1 ^= (ea >> 12) & 0xffff;
        !           213:        hash1 &= (get_hash_size() - 1) >> 6;
        !           214: 
        !           215:        pp = (mPTE_t*)(get_hash_base() + (hash1 << 6));
        !           216:        upte = (unsigned long*)pp;
        !           217: 
        !           218:        /* replace old translation */
        !           219:        for( found=0, i=0; !found && i<8; i++ )
        !           220:                if( cmp == upte[i*2] )
        !           221:                        found=1;
        !           222: 
        !           223:        /* otherwise use a free slot */
        !           224:        for( i=0; !found && i<8; i++ )
        !           225:                if( !pp[i].v )
        !           226:                        found=1;
        !           227: 
        !           228:        /* out of slots, just evict one */
        !           229:        if( !found ) {
        !           230:                i = next_grab_slot + 1;
        !           231:                next_grab_slot = (next_grab_slot + 1) % 8;
        !           232:        }
        !           233:        i--;
        !           234:        upte[i*2] = cmp;
        !           235:        upte[i*2+1] = (phys & ~0xfff) | mode;
        !           236: 
        !           237:        asm volatile( "tlbie %0"  :: "r"(ea) );
        !           238: }
        !           239: 
        !           240: void
        !           241: dsi_exception( void )
        !           242: {
        !           243:        unsigned long dar, dsisr;
        !           244:        ucell mode;
        !           245:        ucell phys;
        !           246: 
        !           247:        asm volatile("mfdar %0" : "=r" (dar) : );
        !           248:        asm volatile("mfdsisr %0" : "=r" (dsisr) : );
        !           249: 
        !           250:        //printk("dsi-exception @ %08lx <%08lx>\n", dar, dsisr );
        !           251: 
        !           252:        phys = ea_to_phys(dar, &mode);
        !           253:        hash_page( dar, phys, mode );
        !           254: }
        !           255: 
        !           256: void
        !           257: isi_exception( void )
        !           258: {
        !           259:        unsigned long nip, srr1;
        !           260:        ucell mode;
        !           261:        ucell phys;
        !           262: 
        !           263:        asm volatile("mfsrr0 %0" : "=r" (nip) : );
        !           264:        asm volatile("mfsrr1 %0" : "=r" (srr1) : );
        !           265: 
        !           266:        //printk("isi-exception @ %08lx <%08lx>\n", nip, srr1 );
        !           267: 
        !           268:        phys = ea_to_phys(nip, &mode);
        !           269:        hash_page( nip, phys, mode );
        !           270: }
        !           271: 
        !           272: 
        !           273: /************************************************************************/
        !           274: /*     init / cleanup                                                  */
        !           275: /************************************************************************/
        !           276: 
        !           277: void
        !           278: setup_mmu( unsigned long code_base, unsigned long code_size, unsigned long ramsize )
        !           279: {
        !           280:        unsigned long sdr1 = HASH_BASE | ((HASH_SIZE-1) >> 16);
        !           281:        unsigned long sr_base = (0x20 << 24) | SEGR_BASE;
        !           282:        unsigned long msr;
        !           283:        int i;
        !           284: 
        !           285:        asm volatile("mtsdr1 %0" :: "r" (sdr1) );
        !           286:        for( i=0; i<16; i++ ) {
        !           287:                int j = i << 28;
        !           288:                asm volatile("mtsrin %0,%1" :: "r" (sr_base + i), "r" (j) );
        !           289:        }
        !           290:        asm volatile("mfmsr %0" : "=r" (msr) : );
        !           291:        msr |= MSR_IR | MSR_DR;
        !           292:        asm volatile("mtmsr %0" :: "r" (msr) );
        !           293: }
        !           294: 
        !           295: void
        !           296: ofmem_init( void )
        !           297: {
        !           298:        ofmem_t *ofmem = OFMEM;
        !           299:        /* In case we can't rely on memory being zero initialized */
        !           300:        memset(ofmem, 0, sizeof(ofmem));
        !           301: 
        !           302:        ofmem->ramsize = RAMSIZE;
        !           303: 
        !           304:        ofmem_claim_phys( 0, FREE_BASE_1, 0 );
        !           305:        ofmem_claim_virt( 0, FREE_BASE_1, 0 );
        !           306:        ofmem_claim_phys( OF_CODE_START, FREE_BASE_2 - OF_CODE_START, 0 );
        !           307:        ofmem_claim_virt( OF_CODE_START, FREE_BASE_2 - OF_CODE_START, 0 );
        !           308: }

unix.superglobalmegacorp.com

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