Annotation of XNU/osfmk/ppc/ppc_vm_init.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * @OSF_COPYRIGHT@
                     24:  */
                     25: /*
                     26:  * @APPLE_FREE_COPYRIGHT@
                     27:  */
                     28: 
                     29: #include <mach_debug.h>
                     30: #include <mach_kdb.h>
                     31: #include <mach_kdp.h>
                     32: #include <debug.h>
                     33: #include <cpus.h>
                     34: 
                     35: #include <mach/vm_types.h>
                     36: #include <mach/vm_param.h>
                     37: #include <mach/thread_status.h>
                     38: #include <kern/misc_protos.h>
                     39: #include <kern/assert.h>
                     40: #include <kern/cpu_number.h>
                     41: 
                     42: #include <ppc/proc_reg.h>
                     43: #include <ppc/Firmware.h>
                     44: #include <ppc/boot.h>
                     45: #include <ppc/misc_protos.h>
                     46: #include <ppc/pmap.h>
                     47: #include <ppc/pmap_internals.h>
                     48: #include <ppc/mem.h>
                     49: #include <ppc/mappings.h>
                     50: #include <ppc/exception.h>
                     51: #include <ppc/mp.h>
                     52: 
                     53: #ifdef __MACHO__
                     54: #include <mach-o/mach_header.h>
                     55: #endif
                     56: 
                     57: extern unsigned int intstack[];        /* declared in start.s */
                     58: extern unsigned int intstack_top_ss;   /* declared in start.s */
                     59: 
                     60: vm_offset_t mem_size;  /* Size of actual physical memory present
                     61:                                                   minus any performance buffer and possibly limited
                     62:                                                   by mem_limit in bytes */
                     63: vm_offset_t mem_actual;        /* The "One True" physical memory size 
                     64:                                                   actually, it's the highest physical address + 1 */
                     65:                                                  
                     66: 
                     67: mem_region_t pmap_mem_regions[PMAP_MEM_REGION_MAX];
                     68: int     pmap_mem_regions_count = 0;    /* No non-contiguous memory regions */
                     69: 
                     70: mem_region_t free_regions[FREE_REGION_MAX];
                     71: int         free_regions_count;
                     72: 
                     73: #ifndef __MACHO__  
                     74: extern unsigned long etext;
                     75: #endif
                     76: 
                     77: unsigned int avail_remaining = 0;
                     78: vm_offset_t first_avail;
                     79: vm_offset_t static_memory_end;
                     80: extern vm_offset_t avail_next;
                     81: 
                     82: #ifdef __MACHO__
                     83: extern struct mach_header _mh_execute_header;
                     84: vm_offset_t sectTEXTB;
                     85: int sectSizeTEXT;
                     86: vm_offset_t sectDATAB;
                     87: int sectSizeDATA;
                     88: vm_offset_t sectOBJCB;
                     89: int sectSizeOBJC;
                     90: vm_offset_t sectLINKB;
                     91: int sectSizeLINK;
                     92: 
                     93: vm_offset_t end, etext, edata;
                     94: #endif
                     95: 
                     96: extern unsigned long exception_entry;
                     97: extern unsigned long exception_end;
                     98: 
                     99: 
                    100: void ppc_vm_init(unsigned int mem_limit, boot_args *args)
                    101: {
                    102:        unsigned int htabmask;
                    103:        unsigned int i, j, batsize, kmapsize;
                    104:        vm_offset_t  addr;
                    105:        int boot_task_end_offset;
                    106:        const char *cpus;
                    107:        mapping         *mp;
                    108:        vm_offset_t first_phys_avail;
                    109:        vm_offset_t             sizeadj, oldstart;
                    110: 
                    111: #ifdef __MACHO__
                    112:        /* Now retrieve addresses for end, edata, and etext 
                    113:         * from MACH-O headers.
                    114:         */
                    115:        sectTEXTB = (vm_offset_t)getsegdatafromheader(
                    116:                &_mh_execute_header, "__TEXT", &sectSizeTEXT);
                    117:        sectDATAB = (vm_offset_t)getsegdatafromheader(
                    118:                &_mh_execute_header, "__DATA", &sectSizeDATA);
                    119:        sectOBJCB = (vm_offset_t)getsegdatafromheader(
                    120:                &_mh_execute_header, "__OBJC", &sectSizeOBJC);
                    121:        sectLINKB = (vm_offset_t)getsegdatafromheader(
                    122:                &_mh_execute_header, "__LINKEDIT", &sectSizeLINK);
                    123: 
                    124:        etext = (vm_offset_t) sectTEXTB + sectSizeTEXT;
                    125:        edata = (vm_offset_t) sectDATAB + sectSizeDATA;
                    126:        end = getlastaddr();
                    127: #if DEBUG
                    128:        printf("sectTEXT: %x, size: %x\n", sectTEXTB, sectSizeTEXT);
                    129:        printf("sectDATA: %x, size: %x\n", sectDATAB, sectSizeDATA);
                    130:        printf("sectOBJC: %x, size: %x\n", sectOBJCB, sectSizeOBJC);
                    131:        printf("sectLINK: %x, size: %x\n", sectLINKB, sectSizeLINK);
                    132:        printf("end: %x\n", end);
                    133: #endif
                    134: #endif /* __MACHO__ */
                    135: 
                    136: /* Stitch valid memory regions together - they may be contiguous
                    137:  * even though they're not already glued together
                    138:  */
                    139:        mem_actual = mem_actual = args->PhysicalDRAM[0].base + args->PhysicalDRAM[0].size;      /* Initialize to the first region size */
                    140:        addr = 0;                                                                                       /* temp use as pointer to previous memory region... */
                    141:        for (i = 1; i < kMaxDRAMBanks; i++) {
                    142:                
                    143:                if (args->PhysicalDRAM[i].size == 0) continue;  /* If region is empty, skip it */
                    144:                
                    145:                if((args->PhysicalDRAM[i].base + args->PhysicalDRAM[i].size) > mem_actual) {    /* New high? */
                    146:                        mem_actual = args->PhysicalDRAM[i].base + args->PhysicalDRAM[i].size;   /* Take the high bid */
                    147:                }
                    148:                
                    149:                if (args->PhysicalDRAM[i].base ==                               /* Does the end of the last hit the start of the next? */
                    150:                  args->PhysicalDRAM[addr].base +
                    151:                  args->PhysicalDRAM[addr].size) {
                    152:                        printf("region 0x%08x size 0x%08x joining region 0x%08x size 0x%08x\n",
                    153:                          args->PhysicalDRAM[addr].base, args->PhysicalDRAM[addr].size,
                    154:                          args->PhysicalDRAM[i].base, args->PhysicalDRAM[i].size);
                    155:                        
                    156:                        args->PhysicalDRAM[addr].size += args->PhysicalDRAM[i].size;    /* Join them */
                    157:                        args->PhysicalDRAM[i].size = 0;
                    158:                        continue;
                    159:                }
                    160:                /* This is now last non-zero region to compare against */
                    161:                addr = i;
                    162:        }
                    163: 
                    164:        /* Go through the list of memory regions passed in via the args
                    165:         * and copy valid entries into the pmap_mem_regions table, adding
                    166:         * further calculated entries.
                    167:         */
                    168:        
                    169:        pmap_mem_regions_count = 0;
                    170:        mem_size = 0;   /* Will use to total memory found so far */
                    171: 
                    172:        for (i = 0; i < kMaxDRAMBanks; i++) {
                    173:                if (args->PhysicalDRAM[i].size == 0)
                    174:                        continue;
                    175: 
                    176:                /* The following should only happen if memory size has
                    177:                   been artificially reduced with -m */
                    178:                if (mem_limit > 0 &&
                    179:                    mem_size + args->PhysicalDRAM[i].size > mem_limit)
                    180:                        args->PhysicalDRAM[i].size = mem_limit - mem_size;
                    181: 
                    182:                /* We've found a region, tally memory */
                    183: 
                    184:                pmap_mem_regions[pmap_mem_regions_count].start =
                    185:                        args->PhysicalDRAM[i].base;
                    186:                pmap_mem_regions[pmap_mem_regions_count].end =
                    187:                        args->PhysicalDRAM[i].base +
                    188:                        args->PhysicalDRAM[i].size;
                    189: 
                    190:                /* Regions must be provided in ascending order */
                    191:                assert ((pmap_mem_regions_count == 0) ||
                    192:                        pmap_mem_regions[pmap_mem_regions_count].start >
                    193:                        pmap_mem_regions[pmap_mem_regions_count-1].start);
                    194: 
                    195:                if (pmap_mem_regions_count > 0) {               
                    196:                        /* we add on any pages not in the first memory
                    197:                         * region to the avail_remaining count. The first
                    198:                         * memory region is used for mapping everything for
                    199:                         * bootup and is taken care of specially.
                    200:                         */
                    201:                        avail_remaining +=
                    202:                                args->PhysicalDRAM[i].size / PPC_PGBYTES;
                    203:                }
                    204:                
                    205:                /* Keep track of how much memory we've found */
                    206: 
                    207:                mem_size += args->PhysicalDRAM[i].size;
                    208: 
                    209:                /* incremement number of regions found */
                    210:                pmap_mem_regions_count++;
                    211:        }
                    212: 
                    213:        printf("mem_size: %d M\n",mem_size / (1024 * 1024));
                    214: 
                    215:        /* 
                    216:         * Initialize the pmap system, using space above `first_avail'
                    217:         * for the necessary data structures.
                    218:         * NOTE : assume that we'll have enough space mapped in already
                    219:         */
                    220: 
                    221:        first_phys_avail = static_memory_end;
                    222:        first_avail = adjust_bat_limit(first_phys_avail, 0, FALSE, FALSE);
                    223:        
                    224:        kmapsize = (round_page(exception_end) - trunc_page(exception_entry)) +  /* Get size we will map later */
                    225:                (round_page(sectTEXTB+sectSizeTEXT) - trunc_page(sectTEXTB)) +
                    226:                (round_page(sectDATAB+sectSizeDATA) - trunc_page(sectDATAB)) +
                    227:                (round_page(sectOBJCB+sectSizeOBJC) - trunc_page(sectOBJCB)) +
                    228:                (round_page(sectLINKB+sectSizeLINK) - trunc_page(sectLINKB)) +
                    229:                (round_page(static_memory_end) - trunc_page(end));
                    230: 
                    231:        pmap_bootstrap(mem_size,&first_avail,&first_phys_avail, kmapsize);
                    232: 
                    233: #ifdef __MACHO__
                    234: #if DEBUG
                    235:        printf("Mapping memory:\n");
                    236:        printf("   exception vector: %08X, %08X - %08X\n", trunc_page(exception_entry), 
                    237:                trunc_page(exception_entry), round_page(exception_end));
                    238:        printf("          sectTEXTB: %08X, %08X - %08X\n", trunc_page(sectTEXTB), 
                    239:                trunc_page(sectTEXTB), round_page(sectTEXTB+sectSizeTEXT));
                    240:        printf("          sectDATAB: %08X, %08X - %08X\n", trunc_page(sectDATAB), 
                    241:                trunc_page(sectDATAB), round_page(sectDATAB+sectSizeDATA));
                    242:        printf("          sectOBJCB: %08X, %08X - %08X\n", trunc_page(sectOBJCB), 
                    243:                trunc_page(sectOBJCB), round_page(sectOBJCB+sectSizeOBJC));
                    244:        printf("          sectLINKB: %08X, %08X - %08X\n", trunc_page(sectLINKB), 
                    245:                trunc_page(sectLINKB), round_page(sectLINKB+sectSizeLINK));
                    246:        printf("                end: %08X, %08X - %08X\n", trunc_page(end), 
                    247:                trunc_page(end), static_memory_end);
                    248: #endif /* DEBUG */
                    249:        pmap_map(trunc_page(exception_entry), trunc_page(exception_entry), 
                    250:                round_page(exception_end), VM_PROT_READ|VM_PROT_EXECUTE);
                    251:        pmap_map(trunc_page(sectTEXTB), trunc_page(sectTEXTB), 
                    252:                round_page(sectTEXTB+sectSizeTEXT), VM_PROT_READ|VM_PROT_EXECUTE);
                    253:        pmap_map(trunc_page(sectDATAB), trunc_page(sectDATAB), 
                    254:                round_page(sectDATAB+sectSizeDATA), VM_PROT_READ|VM_PROT_WRITE);
                    255:        pmap_map(trunc_page(sectOBJCB), trunc_page(sectOBJCB), 
                    256:                round_page(sectOBJCB+sectSizeOBJC), VM_PROT_READ|VM_PROT_WRITE);
                    257:        pmap_map(trunc_page(sectLINKB), trunc_page(sectLINKB), 
                    258:                round_page(sectLINKB+sectSizeLINK), VM_PROT_READ|VM_PROT_WRITE);
                    259:        pmap_map(trunc_page(end), trunc_page(end), 
                    260:                round_page(static_memory_end), VM_PROT_READ|VM_PROT_WRITE);
                    261: #endif /* __MACHO__ */
                    262: 
                    263: #if DEBUG
                    264:        for (i=0 ; i < free_regions_count; i++) {
                    265:                printf("Free region start 0x%08x end 0x%08x\n",
                    266:                       free_regions[i].start,free_regions[i].end);
                    267:        }
                    268: #endif
                    269: 
                    270:        /* Initialize shadow IBATs */
                    271:        shadow_BAT.IBATs[0].upper=BAT_INVALID;
                    272:        shadow_BAT.IBATs[0].lower=BAT_INVALID;
                    273:        shadow_BAT.IBATs[1].upper=BAT_INVALID;
                    274:        shadow_BAT.IBATs[1].lower=BAT_INVALID;
                    275:        shadow_BAT.IBATs[2].upper=BAT_INVALID;
                    276:        shadow_BAT.IBATs[2].lower=BAT_INVALID;
                    277:        shadow_BAT.IBATs[3].upper=BAT_INVALID;
                    278:        shadow_BAT.IBATs[3].lower=BAT_INVALID;
                    279: 
                    280:        LoadIBATs((unsigned int *)&shadow_BAT.IBATs[0]);                /* Load up real IBATs from shadows */
                    281: 
                    282:        /* Initialize shadow DBATs */
                    283:        shadow_BAT.DBATs[0].upper=BAT_INVALID;
                    284:        shadow_BAT.DBATs[0].lower=BAT_INVALID;
                    285:        shadow_BAT.DBATs[1].upper=BAT_INVALID;
                    286:        shadow_BAT.DBATs[1].lower=BAT_INVALID;
                    287:        mfdbatu(shadow_BAT.DBATs[2].upper,2);
                    288:        mfdbatl(shadow_BAT.DBATs[2].lower,2);
                    289:        mfdbatu(shadow_BAT.DBATs[3].upper,3);
                    290:        mfdbatl(shadow_BAT.DBATs[3].lower,3);
                    291: 
                    292:        LoadDBATs((unsigned int *)&shadow_BAT.DBATs[0]);                /* Load up real DBATs from shadows */
                    293: 
                    294:        sync();isync();
                    295: #if DEBUG
                    296:        for(i=0; i<4; i++) printf("DBAT%1d: %08X %08X\n", 
                    297:                i, shadow_BAT.DBATs[i].upper, shadow_BAT.DBATs[i].lower);
                    298:        for(i=0; i<4; i++) printf("IBAT%1d: %08X %08X\n", 
                    299:                i, shadow_BAT.IBATs[i].upper, shadow_BAT.IBATs[i].lower);
                    300: #endif
                    301: }
                    302: 
                    303: void ppc_vm_cpu_init(
                    304:        struct per_proc_info *proc_info)
                    305: {
                    306:        hash_table_init(hash_table_base, hash_table_size);
                    307: 
                    308:        LoadIBATs((unsigned int *)&shadow_BAT.IBATs[0]);
                    309:        LoadDBATs((unsigned int *)&shadow_BAT.DBATs[0]);
                    310: 
                    311:        sync();isync();
                    312: }

unix.superglobalmegacorp.com

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