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

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: 
1.1.1.2 ! root      124: void ofmem_arch_map_pages(ucell phys, ucell virt, ucell size, ucell mode)
1.1       root      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.