Annotation of qemu/roms/openbios/arch/sparc64/ofmem_sparc64.c, revision 1.1.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.