Annotation of qemu/roms/openbios/arch/sparc32/ofmem_sparc32.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  *     <ofmem_sparc32.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"
1.1.1.2 ! root       18: #include "arch/sparc32/ofmem_sparc32.h"
1.1       root       19: #include "asm/asi.h"
                     20: #include "pgtsrmmu.h"
                     21: 
                     22: #define OF_MALLOC_BASE         ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8))
                     23: 
1.1.1.2 ! root       24: #define MEMSIZE (256 * 1024)
1.1       root       25: static union {
                     26:        char memory[MEMSIZE];
                     27:        ofmem_t ofmem;
                     28: } s_ofmem_data;
                     29: 
                     30: #define OFMEM          (&s_ofmem_data.ofmem)
                     31: #define TOP_OF_RAM     (s_ofmem_data.memory + MEMSIZE)
                     32: 
                     33: translation_t **g_ofmem_translations = &s_ofmem_data.ofmem.trans;
                     34: 
                     35: extern uint32_t qemu_mem_size;
                     36: 
                     37: static inline size_t ALIGN_SIZE(size_t x, size_t a)
                     38: {
                     39:     return (x + a - 1) & ~(a-1);
                     40: }
                     41: 
                     42: static ucell get_heap_top( void )
                     43: {
                     44:        return (ucell)TOP_OF_RAM;
                     45: }
                     46: 
                     47: ofmem_t* ofmem_arch_get_private(void)
                     48: {
                     49:        return OFMEM;
                     50: }
                     51: 
                     52: void* ofmem_arch_get_malloc_base(void)
                     53: {
                     54:        return OF_MALLOC_BASE;
                     55: }
                     56: 
                     57: ucell ofmem_arch_get_heap_top(void)
                     58: {
                     59:        return get_heap_top();
                     60: }
                     61: 
                     62: ucell ofmem_arch_get_virt_top(void)
                     63: {
                     64:        return (ucell)TOP_OF_RAM;
                     65: }
                     66: 
                     67: phys_addr_t ofmem_arch_get_phys_top(void)
                     68: {
                     69:        ofmem_t *ofmem = ofmem_arch_get_private();
                     70: 
                     71:        return (uintptr_t)ofmem->ramsize - 0x1000000;
                     72: }
                     73: 
                     74: ucell ofmem_arch_get_iomem_base(void)
                     75: {
                     76:        return pointer2cell(&_end);
                     77: }
                     78: 
                     79: ucell ofmem_arch_get_iomem_top(void)
                     80: {
                     81:        return pointer2cell(&_iomem);
                     82: }
                     83: 
                     84: retain_t *ofmem_arch_get_retained(void)
                     85: {
                     86:        /* Not used */
                     87:        return 0;
                     88: }
                     89: 
                     90: int ofmem_arch_get_physaddr_cellsize(void)
                     91: {
                     92:        return 2;
                     93: }
                     94: 
                     95: int ofmem_arch_encode_physaddr(ucell *p, phys_addr_t value)
                     96: {
                     97:        int n = 0;
                     98: 
                     99:        p[n++] = value >> 32;
                    100:        p[n++] = value;
                    101: 
                    102:        return n;
                    103: }
                    104: 
                    105: int ofmem_arch_get_translation_entry_size(void)
                    106: {
                    107:        /* Return size of a single MMU package translation property entry in cells */
                    108:        return 3;
                    109: }
                    110: 
                    111: void ofmem_arch_create_translation_entry(ucell *transentry, translation_t *t)
                    112: {
                    113:        /* Generate translation property entry for SPARC. While there is no
                    114:        formal documentation for this, both Linux kernel and OpenSolaris sources
                    115:        expect a translation property entry to have the following layout:
                    116: 
                    117:                virtual address
                    118:                length
                    119:                mode
                    120:        */
                    121: 
                    122:        transentry[0] = t->virt;
                    123:        transentry[1] = t->size;
                    124:        transentry[2] = t->mode;
                    125: }
                    126: 
                    127: /* Return the size of a memory available entry given the phandle in cells */
                    128: int ofmem_arch_get_available_entry_size(phandle_t ph)
                    129: {
                    130:        return 1 + ofmem_arch_get_physaddr_cellsize();
                    131: }
                    132: 
                    133: /* Generate memory available property entry for Sparc32 */
                    134: void ofmem_arch_create_available_entry(phandle_t ph, ucell *availentry, phys_addr_t start, ucell size)
                    135: {
1.1.1.2 ! root      136:   int i = 0;
1.1       root      137: 
                    138:        i += ofmem_arch_encode_physaddr(availentry, start);
                    139:        availentry[i] = size;
                    140: }
                    141: 
1.1.1.2 ! root      142: /* Unmap a set of pages */
        !           143: void ofmem_arch_unmap_pages(ucell virt, ucell size)
        !           144: {
        !           145:     /* Currently do nothing */
        !           146: }
        !           147: 
        !           148: /* Map a set of pages */
        !           149: void ofmem_arch_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode)
        !           150: {
        !           151:        unsigned long npages, off;
        !           152:        uint32_t pte;
        !           153:        unsigned long pa;
        !           154: 
        !           155:        off = phys & (PAGE_SIZE - 1);
        !           156:        npages = (off + (size - 1) + (PAGE_SIZE - 1)) / PAGE_SIZE;
        !           157:        phys &= ~(uint64_t)(PAGE_SIZE - 1);
        !           158: 
        !           159:        while (npages-- != 0) {
        !           160:                pa = find_pte(virt, 1);
        !           161: 
        !           162:                pte = SRMMU_ET_PTE | ((phys & PAGE_MASK) >> 4);
        !           163:                pte |= mode;
        !           164: 
        !           165:                *(uint32_t *)pa = pte;
        !           166: 
        !           167:                virt += PAGE_SIZE;
        !           168:                phys += PAGE_SIZE;
        !           169:        }
        !           170: }
        !           171: 
        !           172: /* Architecture-specific OFMEM helpers */
        !           173: unsigned long
        !           174: find_pte(unsigned long va, int alloc)
        !           175: {
        !           176:     uint32_t pte;
        !           177:     void *p;
        !           178:     unsigned long pa;
        !           179:     int ret;
        !           180: 
        !           181:     pte = l1[(va >> SRMMU_PGDIR_SHIFT) & (SRMMU_PTRS_PER_PGD - 1)];
        !           182:     if ((pte & SRMMU_ET_MASK) == SRMMU_ET_INVALID) {
        !           183:         if (alloc) {
        !           184:             ret = ofmem_posix_memalign(&p, SRMMU_PTRS_PER_PMD * sizeof(int),
        !           185:                                  SRMMU_PTRS_PER_PMD * sizeof(int));
        !           186:             if (ret != 0)
        !           187:                 return ret;
        !           188:             pte = SRMMU_ET_PTD | ((va2pa((unsigned long)p)) >> 4);
        !           189:             l1[(va >> SRMMU_PGDIR_SHIFT) & (SRMMU_PTRS_PER_PGD - 1)] = pte;
        !           190:             /* barrier() */
        !           191:         } else {
        !           192:             return -1;
        !           193:         }
        !           194:     }
        !           195: 
        !           196:     pa = (pte & 0xFFFFFFF0) << 4;
        !           197:     pa += ((va >> SRMMU_PMD_SHIFT) & (SRMMU_PTRS_PER_PMD - 1)) << 2;
        !           198:     pte = *(uint32_t *)pa2va(pa);
        !           199:     if ((pte & SRMMU_ET_MASK) == SRMMU_ET_INVALID) {
        !           200:         if (alloc) {
        !           201:             ret = ofmem_posix_memalign(&p, SRMMU_PTRS_PER_PTE * sizeof(void *),
        !           202:                                  SRMMU_PTRS_PER_PTE * sizeof(void *));
        !           203:             if (ret != 0)
        !           204:                 return ret;
        !           205:             pte = SRMMU_ET_PTD | ((va2pa((unsigned int)p)) >> 4);
        !           206:             *(uint32_t *)pa2va(pa) = pte;
        !           207:         } else {
        !           208:             return -2;
        !           209:         }
        !           210:     }
        !           211: 
        !           212:     pa = (pte & 0xFFFFFFF0) << 4;
        !           213:     pa += ((va >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1)) << 2;
        !           214: 
        !           215:     return pa2va(pa);
        !           216: }
        !           217: 
1.1       root      218: /************************************************************************/
                    219: /* misc                                                                 */
                    220: /************************************************************************/
                    221: 
                    222: ucell ofmem_arch_default_translation_mode( phys_addr_t phys )
                    223: {
                    224:        return SRMMU_REF | SRMMU_CACHE | SRMMU_PRIV;
                    225: }
                    226: 
                    227: ucell ofmem_arch_io_translation_mode( phys_addr_t phys )
                    228: {
                    229:        return SRMMU_REF | SRMMU_PRIV;
                    230: }
                    231: 
                    232: /************************************************************************/
                    233: /* init / cleanup                                                       */
                    234: /************************************************************************/
                    235: 
                    236: void ofmem_init( void )
                    237: {
                    238:        memset(&s_ofmem_data, 0, sizeof(s_ofmem_data));
                    239:        s_ofmem_data.ofmem.ramsize = qemu_mem_size;
                    240:        
                    241:        /* Claim reserved physical addresses at top of RAM */
                    242:        ofmem_claim_phys(ofmem_arch_get_phys_top(), s_ofmem_data.ofmem.ramsize - ofmem_arch_get_phys_top(), 0);
                    243:        
                    244:        /* Claim OpenBIOS reserved space */
                    245:        ofmem_claim_virt(0xffd00000, 0x300000, 0);
                    246: }

unix.superglobalmegacorp.com

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