Annotation of qemu/roms/openbios/arch/sparc64/ofmem_sparc64.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     <ofmem_sparc64.c>
        !             3:  *
        !             4:  *     OF Memory manager
        !             5:  *
        !             6:  *   Copyright (C) 1999-2004 Samuel Rydh ([email protected])
        !             7:  *   Copyright (C) 2004 Stefan Reinauer
        !             8:  *
        !             9:  *   This program is free software; you can redistribute it and/or
        !            10:  *   modify it under the terms of the GNU General Public License
        !            11:  *   as published by the Free Software Foundation
        !            12:  *
        !            13:  */
        !            14: 
        !            15: #include "config.h"
        !            16: #include "libopenbios/bindings.h"
        !            17: #include "libc/string.h"
        !            18: #include "ofmem_sparc64.h"
        !            19: #include "spitfire.h"
        !            20: 
        !            21: #define OF_MALLOC_BASE         ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8))
        !            22: 
        !            23: #define MEMSIZE ((256 + 512) * 1024)
        !            24: static union {
        !            25:        char memory[MEMSIZE];
        !            26:        ofmem_t ofmem;
        !            27: } s_ofmem_data;
        !            28: 
        !            29: #define OFMEM          (&s_ofmem_data.ofmem)
        !            30: #define TOP_OF_RAM     (s_ofmem_data.memory + MEMSIZE)
        !            31: 
        !            32: translation_t **g_ofmem_translations = &s_ofmem_data.ofmem.trans;
        !            33: 
        !            34: extern uint64_t qemu_mem_size;
        !            35: 
        !            36: static inline size_t ALIGN_SIZE(size_t x, size_t a)
        !            37: {
        !            38:     return (x + a - 1) & ~(a-1);
        !            39: }
        !            40: 
        !            41: static ucell get_heap_top( void )
        !            42: {
        !            43:        return (ucell)(TOP_OF_RAM - ALIGN_SIZE(sizeof(retain_t), 8));
        !            44: }
        !            45: 
        !            46: ofmem_t* ofmem_arch_get_private(void)
        !            47: {
        !            48:        return OFMEM;
        !            49: }
        !            50: 
        !            51: void* ofmem_arch_get_malloc_base(void)
        !            52: {
        !            53:        return OF_MALLOC_BASE;
        !            54: }
        !            55: 
        !            56: ucell ofmem_arch_get_heap_top(void)
        !            57: {
        !            58:        return get_heap_top();
        !            59: }
        !            60: 
        !            61: ucell ofmem_arch_get_virt_top(void)
        !            62: {
        !            63:        return (ucell)TOP_OF_RAM;
        !            64: }
        !            65: 
        !            66: phys_addr_t ofmem_arch_get_phys_top(void)
        !            67: {
        !            68:        ofmem_t *ofmem = ofmem_arch_get_private();
        !            69: 
        !            70:        return ofmem->ramsize;
        !            71: }
        !            72: 
        !            73: ucell ofmem_arch_get_iomem_base(void)
        !            74: {
        !            75:        /* Currently unused */
        !            76:        return 0;
        !            77: }
        !            78: 
        !            79: ucell ofmem_arch_get_iomem_top(void)
        !            80: {
        !            81:        /* Currently unused */
        !            82:        return 0;
        !            83: }
        !            84: 
        !            85: retain_t *ofmem_arch_get_retained(void)
        !            86: {
        !            87:        /* Retained area is at the top of physical RAM */
        !            88:        return (retain_t *)(qemu_mem_size - sizeof(retain_t));
        !            89: }
        !            90: 
        !            91: int ofmem_arch_get_translation_entry_size(void)
        !            92: {
        !            93:        /* Return size of a single MMU package translation property entry in cells */
        !            94:        return 3;
        !            95: }
        !            96: 
        !            97: void ofmem_arch_create_translation_entry(ucell *transentry, translation_t *t)
        !            98: {
        !            99:        /* Generate translation property entry for SPARC. While there is no
        !           100:        formal documentation for this, both Linux kernel and OpenSolaris sources
        !           101:        expect a translation property entry to have the following layout:
        !           102: 
        !           103:                virtual address
        !           104:                length
        !           105:                mode 
        !           106:        */
        !           107: 
        !           108:        transentry[0] = t->virt;
        !           109:        transentry[1] = t->size;
        !           110:        transentry[2] = t->mode;
        !           111: }
        !           112: 
        !           113: /* Return the size of a memory available entry given the phandle in cells */
        !           114: int ofmem_arch_get_available_entry_size(phandle_t ph)
        !           115: {
        !           116:        if (ph == s_phandle_memory) {
        !           117:                return 1 + ofmem_arch_get_physaddr_cellsize();
        !           118:        } else {
        !           119:                return 1 + 1;
        !           120:        }
        !           121: }
        !           122: 
        !           123: /* Generate memory available property entry for Sparc64 */
        !           124: void ofmem_arch_create_available_entry(phandle_t ph, ucell *availentry, phys_addr_t start, ucell size)
        !           125: {
        !           126:        int i = 0;
        !           127: 
        !           128:        if (ph == s_phandle_memory) {
        !           129:                i += ofmem_arch_encode_physaddr(availentry, start);
        !           130:        } else {
        !           131:                availentry[i++] = start;
        !           132:        }
        !           133:     
        !           134:        availentry[i] = size;
        !           135: }
        !           136: 
        !           137: /************************************************************************/
        !           138: /* misc                                                                 */
        !           139: /************************************************************************/
        !           140: 
        !           141: int ofmem_arch_get_physaddr_cellsize(void)
        !           142: {
        !           143:     return 1;
        !           144: }
        !           145: 
        !           146: int ofmem_arch_encode_physaddr(ucell *p, phys_addr_t value)
        !           147: {
        !           148:     p[0] = value;
        !           149:     return 1;
        !           150: }
        !           151: 
        !           152: ucell ofmem_arch_default_translation_mode( phys_addr_t phys )
        !           153: {
        !           154:        /* Writable, cacheable */
        !           155:        /* not privileged and not locked */
        !           156:        return SPITFIRE_TTE_CP | SPITFIRE_TTE_CV | SPITFIRE_TTE_WRITABLE;
        !           157: }
        !           158: 
        !           159: ucell ofmem_arch_io_translation_mode( phys_addr_t phys )
        !           160: {
        !           161:        /* Writable, not privileged and not locked */
        !           162:        return SPITFIRE_TTE_CV | SPITFIRE_TTE_WRITABLE;
        !           163: }
        !           164: 
        !           165: /************************************************************************/
        !           166: /* init / cleanup                                                       */
        !           167: /************************************************************************/
        !           168: 
        !           169: static int remap_page_range( phys_addr_t phys, ucell virt, ucell size, ucell mode )
        !           170: {
        !           171:        ofmem_claim_phys(phys, size, 0);
        !           172:        ofmem_claim_virt(virt, size, 0);
        !           173:        ofmem_map_page_range(phys, virt, size, mode);
        !           174:        if (!(mode & SPITFIRE_TTE_LOCKED)) {
        !           175:                OFMEM_TRACE("remap_page_range clearing translation " FMT_ucellx
        !           176:                                " -> " FMT_ucellx " " FMT_ucellx " mode " FMT_ucellx "\n",
        !           177:                                virt, phys, size, mode );
        !           178:                ofmem_arch_unmap_pages(virt, size);
        !           179:        }
        !           180:        return 0;
        !           181: }
        !           182: 
        !           183: #define RETAIN_MAGIC   0x1100220033004400
        !           184: 
        !           185: void ofmem_init( void )
        !           186: {
        !           187:        retain_t *retained = ofmem_arch_get_retained();
        !           188:        int i;
        !           189: 
        !           190:        memset(&s_ofmem_data, 0, sizeof(s_ofmem_data));
        !           191:        s_ofmem_data.ofmem.ramsize = qemu_mem_size;
        !           192: 
        !           193:        /* inherit translations set up by entry.S */
        !           194:        ofmem_walk_boot_map(remap_page_range);
        !           195: 
        !           196:         /* Map the memory */
        !           197:         ofmem_map_page_range(0, 0, qemu_mem_size, 0x36);
        !           198: 
        !           199:        if (!(retained->magic == RETAIN_MAGIC)) {
        !           200:                OFMEM_TRACE("ofmem_init: no retained magic found, creating\n");
        !           201:                retained->magic = RETAIN_MAGIC;
        !           202:                retained->numentries = 0;
        !           203:        } else {
        !           204:                OFMEM_TRACE("ofmem_init: retained magic found, total %lld mappings\n", retained->numentries);   
        !           205: 
        !           206:                /* Mark physical addresses as used so they are not reallocated */
        !           207:                for (i = 0; i < retained->numentries; i++) {
        !           208:                        ofmem_claim_phys(retained->retain_phys_range[i].start, 
        !           209:                                retained->retain_phys_range[i].size, 0);
        !           210:                }
        !           211: 
        !           212:                /* Reset retained area for next reset */
        !           213:                retained->magic = RETAIN_MAGIC;
        !           214:                retained->numentries = 0;
        !           215:        }
        !           216: }

unix.superglobalmegacorp.com

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