[BACK]Return to boot32.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / acorn32 / stand / boot32

Annotation of src/sys/arch/acorn32/stand/boot32/boot32.c, Revision 1.30.34.1

1.30.34.1! bouyer      1: /*     $NetBSD$        */
1.1       reinoud     2:
                      3: /*-
                      4:  * Copyright (c) 2002 Reinoud Zandijk
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. The name of the author may not be used to endorse or promote products
                     16:  *    derived from this software without specific prior written permission.
1.22      bjh21      17:  *
1.1       reinoud    18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     23:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     24:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     25:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     26:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     27:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     28:  *
                     29:  * Thanks a bunch for Ben's framework for the bootloader and its suporting
                     30:  * libs. This file tries to actually boot NetBSD/acorn32 !
                     31:  *
                     32:  * XXX eventually to be partly merged back with boot26 ? XXX
                     33:  */
                     34:
                     35: #include <lib/libsa/stand.h>
                     36: #include <lib/libsa/loadfile.h>
                     37: #include <lib/libkern/libkern.h>
                     38: #include <riscoscalls.h>
                     39: #include <srt0.h>
                     40: #include <sys/boot_flag.h>
                     41: #include <machine/vmparam.h>
                     42: #include <arm/arm32/pte.h>
                     43: #include <machine/bootconfig.h>
                     44:
1.19      abs        45: extern char end[];
1.1       reinoud    46:
                     47: /* debugging flags */
                     48: int debug = 1;
                     49:
                     50:
                     51: /* constants */
1.21      bjh21      52: #define PODRAM_START   (512*1024*1024)         /* XXX Kinetic cards XXX */
1.1       reinoud    53:
                     54: #define MAX_RELOCPAGES 4096
                     55:
                     56: #define DEFAULT_ROOT   "/dev/wd0a"
                     57:
                     58:
                     59: #define IO_BLOCKS       16     /* move these to the bootloader structure? */
                     60: #define ROM_BLOCKS      16
                     61: #define PODRAM_BLOCKS   16
                     62:
                     63:
                     64: /* booter variables */
1.21      bjh21      65: char    scrap[80], twirl_cnt;          /* misc                         */
1.1       reinoud    66: char    booted_file[80];
                     67:
1.21      bjh21      68: struct bootconfig *bconfig;            /* bootconfig passing           */
                     69: u_long  bconfig_new_phys;              /* physical address its bound   */
1.1       reinoud    70:
1.21      bjh21      71: /* computer knowledge          */
                     72: u_int   monitor_type, monitor_sync, ioeb_flags, lcd_flags;
1.1       reinoud    73: u_int   superio_flags, superio_flags_basic, superio_flags_extra;
                     74:
1.21      bjh21      75: /* sizes                       */
                     76: int     nbpp, memory_table_size, memory_image_size;
                     77: /* relocate info               */
                     78: u_long  reloc_tablesize, *reloc_instruction_table;
                     79: u_long *reloc_pos;                     /* current empty entry          */
                     80: int     reloc_entries;                 /* number of relocations        */
                     81: int     first_mapped_DRAM_page_index;  /* offset in RISC OS blob       */
                     82: int     first_mapped_PODRAM_page_index;/* offset in RISC OS blob       */
                     83:
                     84: struct page_info *mem_pages_info;      /* {nr, virt, phys}*            */
                     85: struct page_info *free_relocation_page;        /* points to the page_info chain*/
                     86: struct page_info *relocate_table_pages;        /* points to seq. relocate info */
                     87: struct page_info *relocate_code_page;  /* points to the copied code    */
                     88: struct page_info *bconfig_page;                /* page for passing on settings */
1.1       reinoud    89:
1.21      bjh21      90: unsigned char *memory_page_types;      /* packed array of 4 bit typeId */
1.1       reinoud    91:
1.21      bjh21      92: u_long *initial_page_tables;           /* pagetables to be booted from */
1.1       reinoud    93:
                     94:
                     95: /* XXX rename *_BLOCKS to MEM_BLOCKS */
                     96: /* DRAM/VRAM/ROM/IO info */
1.21      bjh21      97: /* where the display is                */
                     98: u_long  videomem_start, videomem_pages, display_size;
1.14      bjh21      99:
1.21      bjh21     100: u_long  pv_offset, top_physdram;       /* kernel_base - phys. diff     */
                    101: u_long  top_1Mb_dram;                  /* the lower mapped top 1Mb     */
                    102: u_long  new_L1_pages_phys;             /* physical address of L1 pages */
                    103:
                    104: /* for bootconfig passing      */
                    105: u_long  total_podram_pages, total_dram_pages, total_vram_pages;
                    106: int     dram_blocks, podram_blocks;    /* number of mem. objects/type  */
1.1       reinoud   107: int     vram_blocks, rom_blocks, io_blocks;
                    108:
1.2       reinoud   109: u_long  DRAM_addr[DRAM_BLOCKS],     DRAM_pages[DRAM_BLOCKS];
1.21      bjh21     110: /* processor only RAM  */
                    111: u_long  PODRAM_addr[PODRAM_BLOCKS], PODRAM_pages[PODRAM_BLOCKS];
1.2       reinoud   112: u_long  VRAM_addr[VRAM_BLOCKS],     VRAM_pages[VRAM_BLOCKS];
                    113: u_long  ROM_addr[ROM_BLOCKS],       ROM_pages[ROM_BLOCKS];
                    114: u_long  IO_addr[IO_BLOCKS],         IO_pages[IO_BLOCKS];
1.1       reinoud   115:
                    116:
                    117: /* RISC OS memory pages we claimed */
1.21      bjh21     118: u_long  firstpage, lastpage, totalpages; /* RISC OS pagecounters       */
                    119: /* RISC OS memory              */
                    120: char   *memory_image, *bottom_memory, *top_memory;
1.1       reinoud   121:
1.21      bjh21     122: u_long  videomem_start_ro;             /* for debugging mainly         */
1.1       reinoud   123:
                    124: /* kernel info */
1.22      bjh21     125: u_long  marks[MARK_MAX];               /* loader mark pointers         */
1.21      bjh21     126: u_long  kernel_physical_start;         /* where does it get relocated  */
                    127: u_long  kernel_free_vm_start;          /* where does the free VM start */
                    128: /* some free space to mess with        */
                    129: u_long  scratch_virtualbase, scratch_physicalbase;
1.1       reinoud   130:
                    131:
                    132: /* bootprogram identifiers */
                    133: extern const char bootprog_rev[];
                    134: extern const char bootprog_name[];
                    135: extern const char bootprog_date[];
                    136: extern const char bootprog_maker[];
                    137:
                    138:
                    139: /* predefines / prototypes */
                    140: void    init_datastructures(void);
                    141: void    get_memory_configuration(void);
                    142: void    get_memory_map(void);
                    143: void    create_initial_page_tables(void);
                    144: void    add_pagetables_at_top(void);
1.18      abs       145: int     page_info_cmp(const void *a, const void *);
1.1       reinoud   146: void    add_initvectors(void);
                    147: void    create_configuration(int argc, char **argv, int start_args);
                    148: void    prepare_and_check_relocation_system(void);
                    149: void    twirl(void);
                    150: int     vdu_var(int);
1.21      bjh21     151: void    process_args(int argc, char **argv, int *howto, char *file,
                    152:     int *start_args);
1.1       reinoud   153:
1.24      bjh21     154: char            *sprint0(int width, char prefix, char base, int value);
1.1       reinoud   155: struct page_info *get_relocated_page(u_long destination, int size);
                    156:
                    157: extern void start_kernel(
                    158:                int relocate_code_page,
                    159:                int relocation_pv_offset,
                    160:                int configuration_structure_in_flat_physical_space,
                    161:                int physical_address_of_relocation_tables,
                    162:                int physical_address_of_new_L1_pages,
                    163:                int kernel_entry_point
                    164:                );      /* asm */
                    165:
                    166:
                    167: /* the loader itself */
1.22      bjh21     168: void
                    169: init_datastructures(void)
                    170: {
                    171:
1.1       reinoud   172:        /* Get number of pages and the memorytablesize */
                    173:        osmemory_read_arrangement_table_size(&memory_table_size, &nbpp);
                    174:
1.19      abs       175:        /* Allocate 99% - (small fixed amount) of the heap for memory_image */
                    176:        memory_image_size = (int)HIMEM - (int)end - 512 * 1024;
                    177:        memory_image_size /= 100;
                    178:        memory_image_size *= 99;
1.16      reinoud   179:        if (memory_image_size <= 256*1024)
1.17      gavan     180:                panic("Insufficient memory");
1.16      reinoud   181:
1.1       reinoud   182:        memory_image = alloc(memory_image_size);
1.16      reinoud   183:        if (!memory_image)
                    184:                panic("Can't alloc get my memory image ?");
1.1       reinoud   185:
                    186:        bottom_memory = memory_image;
                    187:        top_memory    = memory_image + memory_image_size;
                    188:
1.22      bjh21     189:        firstpage  = ((int)bottom_memory / nbpp) + 1;   /* safety */
                    190:        lastpage   = ((int)top_memory    / nbpp) - 1;
1.1       reinoud   191:        totalpages = lastpage - firstpage;
                    192:
1.19      abs       193:        printf("Allocated %ld memory pages, each of %d kilobytes.\n\n",
                    194:                        totalpages, nbpp>>10 );
1.1       reinoud   195:
1.16      reinoud   196:        /*
                    197:         * Setup the relocation table. Its a simple array of 3 * 32 bit
                    198:         * entries. The first word in the array is the number of relocations
                    199:         * to be done
                    200:         */
                    201:        reloc_tablesize = (MAX_RELOCPAGES+1)*3*sizeof(u_long);
1.1       reinoud   202:        reloc_instruction_table = alloc(reloc_tablesize);
1.16      reinoud   203:        if (!reloc_instruction_table)
                    204:                panic("Can't alloc my relocate instructions pages");
                    205:
1.1       reinoud   206:        reloc_entries = 0;
                    207:        reloc_pos     = reloc_instruction_table;
                    208:        *reloc_pos++  = 0;
                    209:
1.16      reinoud   210:        /*
                    211:         * Set up the memory translation info structure. We need to allocate
                    212:         * one more for the end of list marker. See get_memory_map.
                    213:         */
1.1       reinoud   214:        mem_pages_info = alloc((totalpages + 1)*sizeof(struct page_info));
1.16      reinoud   215:        if (!mem_pages_info)
                    216:                panic("Can't alloc my phys->virt page info");
1.1       reinoud   217:
1.16      reinoud   218:        /*
                    219:         * Allocate memory for the memory arrangement table. We use this
                    220:         * structure to retrieve memory page properties to clasify them.
                    221:         */
1.1       reinoud   222:        memory_page_types = alloc(memory_table_size);
1.16      reinoud   223:        if (!memory_page_types)
                    224:                panic("Can't alloc my memory page type block");
1.1       reinoud   225:
1.16      reinoud   226:        /*
                    227:         * Initial page tables is 16 kb per definition since only sections are
                    228:         * used.
                    229:         */
                    230:        initial_page_tables = alloc(16*1024);
                    231:        if (!initial_page_tables)
                    232:                panic("Can't alloc my initial page tables");
1.1       reinoud   233: }
                    234:
                    235:
1.22      bjh21     236: void
                    237: prepare_and_check_relocation_system(void)
                    238: {
1.10      reinoud   239:        int     relocate_size, relocate_pages;
                    240:        int     bank, pages, found;
                    241:        u_long  dst, src, base, destination, extend;
                    242:        u_long *reloc_entry, last_src, length;
1.1       reinoud   243:
                    244:        /* set the number of relocation entries in the 1st word */
                    245:        *reloc_instruction_table = reloc_entries;
                    246:
1.16      reinoud   247:        /*
                    248:         * The relocate information needs to be in one sequential physical
                    249:         * space in order to be able to access it as one stream when the MMU
                    250:         * is switched off later.
                    251:         */
                    252:        relocate_size = (reloc_tablesize + nbpp-1) & ~(nbpp-1);  /* round up */
1.1       reinoud   253:        printf("\nPreparing for booting %s ... ", booted_file);
                    254:        relocate_pages = relocate_size / nbpp;
                    255:
                    256:        relocate_table_pages = free_relocation_page;
                    257:        pages = 0;
                    258:        while (pages < relocate_pages) {
1.22      bjh21     259:                src = (u_long)reloc_instruction_table + pages*nbpp;
1.25      bjh21     260:                dst = relocate_table_pages[pages].logical;
1.22      bjh21     261:                memcpy((void *)dst, (void *)src, nbpp);
1.1       reinoud   262:
1.22      bjh21     263:                if (pages < relocate_pages - 1) {
1.1       reinoud   264:                        /* check if next page is sequential physically */
1.25      bjh21     265:                        if (relocate_table_pages[pages+1].physical -
                    266:                            relocate_table_pages[pages].physical != nbpp) {
1.21      bjh21     267:                                /*
                    268:                                 * Non contigunous relocate area ->
                    269:                                 * try again
                    270:                                 */
1.1       reinoud   271:                                printf("*");
                    272:                                relocate_table_pages += pages;
1.26      bjh21     273:                                pages = 0;
1.16      reinoud   274:                                continue;       /* while */
1.22      bjh21     275:                        }
                    276:                }
1.1       reinoud   277:                pages++;
1.22      bjh21     278:        }
1.1       reinoud   279:        free_relocation_page = relocate_table_pages + pages;
                    280:
                    281:        /* copy the relocation code into this page in start_kernel */
                    282:        relocate_code_page = free_relocation_page++;
                    283:
                    284:        /*
                    285:         * All relocations are pages allocated in one big strict increasing
                    286:         * physical DRAM address sequence. When the MMU is switched off all
                    287:         * code and data is in this increasing order but not at the right
                    288:         * place. This is where the relocation code kicks in; relocation is
                    289:         * done in flat physical memory without MMU.
                    290:         */
                    291:
1.10      reinoud   292:        printf("shift and check ... ");
1.1       reinoud   293:        reloc_entry = reloc_instruction_table + 1;
1.10      reinoud   294:        last_src = -1;
1.1       reinoud   295:        while (reloc_entry < reloc_pos) {
1.10      reinoud   296:                src         = reloc_entry[0];
                    297:                destination = reloc_entry[1];
                    298:                length      = reloc_entry[2];
                    299:
                    300:                /* paranoia check */
1.21      bjh21     301:                if ((long) (src - last_src) <= 0)
                    302:                        printf("relocation sequence challenged -- "
                    303:                            "booting might fail ");
1.10      reinoud   304:                last_src = src;
                    305:
                    306:                /* check if its gonna be relocated into (PO)DRAM ! */
                    307:                extend = destination + length;
                    308:                found = 0;
                    309:                for (bank = 0; (bank < dram_blocks) && !found; bank++) {
                    310:                        base   = DRAM_addr[bank];
1.21      bjh21     311:                        found = (destination >= base) &&
                    312:                            (extend <= base + DRAM_pages[bank]*nbpp);
1.22      bjh21     313:                }
1.10      reinoud   314:                for (bank = 0; (bank < podram_blocks) && !found; bank++) {
                    315:                        base = PODRAM_addr[bank];
1.21      bjh21     316:                        found = (destination >= base) &&
                    317:                            (extend <= base + PODRAM_pages[bank]*nbpp);
1.22      bjh21     318:                }
1.10      reinoud   319:                if (!found || (extend > top_physdram)) {
1.22      bjh21     320:                        panic("Internal error: relocating range "
1.21      bjh21     321:                            "[%lx +%lx => %lx] outside (PO)DRAM banks!",
1.22      bjh21     322:                            src, length, destination);
                    323:                }
1.1       reinoud   324:
1.22      bjh21     325:                reloc_entry += 3;
                    326:        }
1.21      bjh21     327:        if (reloc_entry != reloc_pos)
                    328:                panic("Relocation instruction table is corrupted");
1.22      bjh21     329:
1.1       reinoud   330:        printf("OK!\n");
                    331: }
                    332:
                    333:
1.22      bjh21     334: void
                    335: get_memory_configuration(void)
                    336: {
1.1       reinoud   337:        int loop, current_page_type, page_count, phys_page;
1.15      reinoud   338:        int page, count, bank, top_bank, video_bank;
1.1       reinoud   339:        int mapped_screen_memory;
1.15      reinoud   340:        int one_mb_pages;
                    341:        u_long top;
1.1       reinoud   342:
                    343:        printf("Getting memory configuration ");
                    344:
                    345:        osmemory_read_arrangement_table(memory_page_types);
                    346:
                    347:        /* init counters */
1.21      bjh21     348:        bank = vram_blocks = dram_blocks = rom_blocks = io_blocks =
                    349:            podram_blocks = 0;
1.1       reinoud   350:
                    351:        current_page_type = -1;
                    352:        phys_page = 0;                  /* physical address in pages    */
                    353:        page_count = 0;                 /* page counter in this block   */
                    354:        loop = 0;                       /* loop variable over entries   */
                    355:
                    356:        /* iterating over a packed array of 2 page types/byte i.e. 8 kb/byte */
                    357:        while (loop < 2*memory_table_size) {
1.22      bjh21     358:                page = memory_page_types[loop / 2];     /* read twice */
1.21      bjh21     359:                if (loop & 1) page >>= 4;               /* take other nibble */
1.1       reinoud   360:
1.21      bjh21     361:                /*
                    362:                 * bits 0-2 give type, bit3 means the bit page is
                    363:                 * allocatable
                    364:                 */
                    365:                page &= 0x7;                    /* only take bottom 3 bits */
1.1       reinoud   366:                if (page != current_page_type) {
1.21      bjh21     367:                        /* passed a boundary ... note this block           */
                    368:                        /*
                    369:                         * splitting in different vars is for
                    370:                         * compatability reasons
                    371:                         */
1.1       reinoud   372:                        switch (current_page_type) {
1.22      bjh21     373:                        case -1:
                    374:                        case  0:
                    375:                                break;
                    376:                        case osmemory_TYPE_DRAM:
                    377:                                if (phys_page < PODRAM_START) {
                    378:                                        DRAM_addr[dram_blocks]  =
1.21      bjh21     379:                                            phys_page * nbpp;
1.22      bjh21     380:                                        DRAM_pages[dram_blocks] =
                    381:                                            page_count;
                    382:                                        dram_blocks++;
                    383:                                } else {
                    384:                                        PODRAM_addr[podram_blocks]  =
1.21      bjh21     385:                                            phys_page * nbpp;
1.22      bjh21     386:                                        PODRAM_pages[podram_blocks] =
                    387:                                            page_count;
                    388:                                        podram_blocks++;
                    389:                                }
                    390:                                break;
                    391:                        case osmemory_TYPE_VRAM:
                    392:                                VRAM_addr[vram_blocks]  = phys_page * nbpp;
                    393:                                VRAM_pages[vram_blocks] = page_count;
                    394:                                vram_blocks++;
                    395:                                break;
                    396:                        case osmemory_TYPE_ROM:
                    397:                                ROM_addr[rom_blocks]  = phys_page * nbpp;
                    398:                                ROM_pages[rom_blocks] = page_count;
                    399:                                rom_blocks++;
                    400:                                break;
                    401:                        case osmemory_TYPE_IO:
                    402:                                IO_addr[io_blocks]  = phys_page * nbpp;
                    403:                                IO_pages[io_blocks] = page_count;
                    404:                                io_blocks++;
                    405:                                break;
                    406:                        default:
                    407:                                printf("WARNING : found unknown "
                    408:                                    "memory object %d ", current_page_type);
1.24      bjh21     409:                                printf(" at 0x%s",
                    410:                                    sprint0(8,'0','x', phys_page * nbpp));
                    411:                                printf(" for %s k\n",
                    412:                                    sprint0(5,' ','d', (page_count*nbpp)>>10));
1.22      bjh21     413:                                break;
                    414:                        }
1.1       reinoud   415:                        current_page_type = page;
                    416:                        phys_page = loop;
                    417:                        page_count = 0;
1.22      bjh21     418:                }
1.21      bjh21     419:                /*
                    420:                 * smallest unit we recognise is one page ... silly
                    421:                 * could be upto 64 pages i.e. 256 kb
                    422:                 */
1.1       reinoud   423:                page_count += 1;
                    424:                loop       += 1;
                    425:                if ((loop & 31) == 0) twirl();
1.22      bjh21     426:        }
1.1       reinoud   427:
                    428:        printf(" \n\n");
                    429:
                    430:        if (VRAM_pages[0] == 0) {
1.11      reinoud   431:                /* map DRAM as video memory */
1.22      bjh21     432:                display_size     =
                    433:                    vdu_var(os_VDUVAR_TOTAL_SCREEN_SIZE) & ~(nbpp-1);
1.5       reinoud   434: #if 0
1.21      bjh21     435:                mapped_screen_memory = 1024 * 1024; /* max allowed on RiscPC */
1.6       reinoud   436:                videomem_pages   = (mapped_screen_memory / nbpp);
1.1       reinoud   437:                videomem_start   = DRAM_addr[0];
                    438:                DRAM_addr[0]    += videomem_pages * nbpp;
1.3       reinoud   439:                DRAM_pages[0]   -= videomem_pages;
1.5       reinoud   440: #else
                    441:                mapped_screen_memory = display_size;
1.22      bjh21     442:                videomem_pages   = mapped_screen_memory / nbpp;
1.15      reinoud   443:                one_mb_pages     = (1024*1024)/nbpp;
1.6       reinoud   444:
1.15      reinoud   445:                /*
                    446:                 * OK... we need one Mb at the top for compliance with current
                    447:                 * kernel structure. This ought to be abolished one day IMHO.
                    448:                 * Also we have to take care that the kernel needs to be in
                    449:                 * DRAM0a and even has to start there.
                    450:                 * XXX one Mb simms are the smallest supported XXX
                    451:                 */
                    452:                top_bank = dram_blocks-1;
                    453:                video_bank = top_bank;
                    454:                if (DRAM_pages[top_bank] == one_mb_pages) video_bank--;
                    455:
                    456:                if (DRAM_pages[video_bank] < videomem_pages)
1.21      bjh21     457:                        panic("Weird memory configuration found; please "
                    458:                            "contact acorn32 portmaster.");
1.15      reinoud   459:
                    460:                /* split off the top 1Mb */
1.21      bjh21     461:                DRAM_addr [top_bank+1]  = DRAM_addr[top_bank] +
                    462:                    (DRAM_pages[top_bank] - one_mb_pages)*nbpp;
1.15      reinoud   463:                DRAM_pages[top_bank+1]  = one_mb_pages;
                    464:                DRAM_pages[top_bank  ] -= one_mb_pages;
                    465:                dram_blocks++;
                    466:
                    467:                /* Map video memory at the end of the choosen DIMM */
1.21      bjh21     468:                videomem_start          = DRAM_addr[video_bank] +
                    469:                    (DRAM_pages[video_bank] - videomem_pages)*nbpp;
1.15      reinoud   470:                DRAM_pages[video_bank] -= videomem_pages;
                    471:
                    472:                /* sanity */
                    473:                if (DRAM_pages[top_bank] == 0) {
                    474:                        DRAM_addr [top_bank] = DRAM_addr [top_bank+1];
                    475:                        DRAM_pages[top_bank] = DRAM_pages[top_bank+1];
                    476:                        dram_blocks--;
1.22      bjh21     477:                }
1.5       reinoud   478: #endif
1.1       reinoud   479:        } else {
                    480:                /* use VRAM */
                    481:                mapped_screen_memory = 0;
                    482:                videomem_start   = VRAM_addr[0];
                    483:                videomem_pages   = VRAM_pages[0];
                    484:                display_size     = videomem_pages * nbpp;
1.22      bjh21     485:        }
1.1       reinoud   486:
                    487:        if (mapped_screen_memory) {
1.22      bjh21     488:                printf("Used %d kb DRAM ", mapped_screen_memory / 1024);
1.24      bjh21     489:                printf("at 0x%s for video memory\n",
                    490:                    sprint0(8,'0','x', videomem_start));
1.22      bjh21     491:        }
1.1       reinoud   492:
1.15      reinoud   493:        /* find top of (PO)DRAM pages */
1.6       reinoud   494:        top_physdram = 0;
1.15      reinoud   495:        for (loop = 0; loop < podram_blocks; loop++) {
                    496:                top = PODRAM_addr[loop] + PODRAM_pages[loop]*nbpp;
                    497:                if (top > top_physdram) top_physdram = top;
1.22      bjh21     498:        }
1.15      reinoud   499:        for (loop = 0; loop < dram_blocks; loop++) {
                    500:                top = DRAM_addr[loop] + DRAM_pages[loop]*nbpp;
                    501:                if (top > top_physdram) top_physdram = top;
1.22      bjh21     502:        }
1.21      bjh21     503:        if (top_physdram == 0)
                    504:                panic("reality check: No DRAM in this machine?");
1.15      reinoud   505:        if (((top_physdram >> 20) << 20) != top_physdram)
1.21      bjh21     506:                panic("Top is not not aligned on a Mb; "
                    507:                    "remove very small DIMMS?");
1.6       reinoud   508:
1.1       reinoud   509:        videomem_start_ro = vdu_var(os_VDUVAR_DISPLAY_START);
                    510:
                    511:        /* pretty print the individual page types */
                    512:        for (count = 0; count < rom_blocks; count++) {
                    513:                printf("Found ROM  (%d)", count);
1.24      bjh21     514:                printf(" at 0x%s", sprint0(8,'0','x', ROM_addr[count]));
                    515:                printf(" for %s k\n",
                    516:                    sprint0(5,' ','d', (ROM_pages[count]*nbpp)>>10));
1.22      bjh21     517:        }
1.1       reinoud   518:
                    519:        for (count = 0; count < io_blocks; count++) {
                    520:                printf("Found I/O  (%d)", count);
1.24      bjh21     521:                printf(" at 0x%s", sprint0(8,'0','x', IO_addr[count]));
                    522:                printf(" for %s k\n",
                    523:                    sprint0(5,' ','d', (IO_pages[count]*nbpp)>>10));
1.22      bjh21     524:        }
1.1       reinoud   525:
                    526:        /* for DRAM/VRAM also count the number of pages */
                    527:        total_dram_pages = 0;
                    528:        for (count = 0; count < dram_blocks; count++) {
                    529:                total_dram_pages += DRAM_pages[count];
                    530:                printf("Found DRAM (%d)", count);
1.24      bjh21     531:                printf(" at 0x%s", sprint0(8,'0','x', DRAM_addr[count]));
                    532:                printf(" for %s k\n",
                    533:                    sprint0(5,' ','d', (DRAM_pages[count]*nbpp)>>10));
1.22      bjh21     534:        }
1.1       reinoud   535:
                    536:        total_vram_pages = 0;
                    537:        for (count = 0; count < vram_blocks; count++) {
                    538:                total_vram_pages += VRAM_pages[count];
                    539:                printf("Found VRAM (%d)", count);
1.24      bjh21     540:                printf(" at 0x%s", sprint0(8,'0','x', VRAM_addr[count]));
                    541:                printf(" for %s k\n",
                    542:                    sprint0(5,' ','d', (VRAM_pages[count]*nbpp)>>10));
1.22      bjh21     543:        }
1.1       reinoud   544:
                    545:        total_podram_pages = 0;
                    546:        for (count = 0; count < podram_blocks; count++) {
                    547:                total_podram_pages += PODRAM_pages[count];
                    548:                printf("Found Processor only (S)DRAM (%d)", count);
1.24      bjh21     549:                printf(" at 0x%s", sprint0(8,'0','x', PODRAM_addr[count]));
                    550:                printf(" for %s k\n",
                    551:                    sprint0(5,' ','d', (PODRAM_pages[count]*nbpp)>>10));
1.22      bjh21     552:        }
1.1       reinoud   553: }
                    554:
                    555:
1.22      bjh21     556: void
                    557: get_memory_map(void)
                    558: {
1.1       reinoud   559:        struct page_info *page_info;
                    560:        int     page, inout;
                    561:        int     phys_addr;
                    562:
                    563:        printf("\nGetting actual memorymapping");
1.21      bjh21     564:        for (page = 0, page_info = mem_pages_info;
                    565:             page < totalpages;
                    566:             page++, page_info++) {
1.1       reinoud   567:                page_info->pagenumber = 0;      /* not used */
                    568:                page_info->logical    = (firstpage + page) * nbpp;
                    569:                page_info->physical   = 0;      /* result comes here */
                    570:                /* to avoid triggering a `bug' in RISC OS 4, page it in */
1.22      bjh21     571:                *((int *)page_info->logical) = 0;
                    572:        }
1.1       reinoud   573:        /* close list */
                    574:        page_info->pagenumber = -1;
                    575:
1.21      bjh21     576:        inout = osmemory_GIVEN_LOG_ADDR | osmemory_RETURN_PAGE_NO |
                    577:            osmemory_RETURN_PHYS_ADDR;
1.1       reinoud   578:        osmemory_page_op(inout, mem_pages_info, totalpages);
                    579:
                    580:        printf(" ; sorting ");
1.18      abs       581:        qsort(mem_pages_info, totalpages, sizeof(struct page_info),
                    582:            &page_info_cmp);
1.1       reinoud   583:        printf(".\n");
                    584:
1.21      bjh21     585:        /*
                    586:         * get the first DRAM index and show the physical memory
                    587:         * fragments we got
                    588:         */
1.1       reinoud   589:        printf("\nFound physical memory blocks :\n");
                    590:        first_mapped_DRAM_page_index = -1;
                    591:        first_mapped_PODRAM_page_index = -1;
                    592:        for (page=0; page < totalpages; page++) {
                    593:                phys_addr = mem_pages_info[page].physical;
                    594:                printf("[0x%x", phys_addr);
                    595:                while (mem_pages_info[page+1].physical - phys_addr == nbpp) {
1.22      bjh21     596:                        if (first_mapped_DRAM_page_index < 0 &&
                    597:                            phys_addr >= DRAM_addr[0])
1.1       reinoud   598:                                first_mapped_DRAM_page_index = page;
1.22      bjh21     599:                        if (first_mapped_PODRAM_page_index < 0 &&
                    600:                            phys_addr >= PODRAM_addr[0])
1.1       reinoud   601:                                first_mapped_PODRAM_page_index = page;
                    602:                        page++;
                    603:                        phys_addr = mem_pages_info[page].physical;
1.22      bjh21     604:                }
                    605:                printf("-0x%x]  ", phys_addr + nbpp -1);
                    606:        }
1.1       reinoud   607:        printf("\n\n");
1.22      bjh21     608:        if (first_mapped_PODRAM_page_index < 0 && PODRAM_addr[0])
                    609:                panic("Found no (S)DRAM mapped in the bootloader");
1.21      bjh21     610:        if (first_mapped_DRAM_page_index < 0)
                    611:                panic("No DRAM mapped in the bootloader");
1.1       reinoud   612: }
                    613:
                    614:
1.22      bjh21     615: void
                    616: create_initial_page_tables(void)
                    617: {
1.1       reinoud   618:        u_long page, section, addr, kpage;
                    619:
                    620:        /* mark a section by the following bits and domain 0, AP=01, CB=0 */
1.22      bjh21     621:        /*         A         P         C        B        section
1.21      bjh21     622:                   domain               */
                    623:        section = (0<<11) | (1<<10) | (0<<3) | (0<<2) | (1<<4) | (1<<1) |
                    624:            (0) | (0 << 5);
1.1       reinoud   625:
                    626:        /* first of all a full 1:1 mapping */
1.22      bjh21     627:        for (page = 0; page < 4*1024; page++)
1.1       reinoud   628:                initial_page_tables[page] = (page<<20) | section;
                    629:
1.21      bjh21     630:        /*
                    631:         * video memory is mapped 1:1 in the DRAM section or in VRAM
                    632:         * section
1.22      bjh21     633:         *
1.21      bjh21     634:         * map 1Mb from top of DRAM memory to bottom 1Mb of virtual memmap
                    635:         */
1.9       reinoud   636:        top_1Mb_dram = (((top_physdram - 1024*1024) >> 20) << 20);
1.15      reinoud   637:
1.9       reinoud   638:        initial_page_tables[0] = top_1Mb_dram | section;
1.1       reinoud   639:
1.21      bjh21     640:        /*
                    641:         * map 16 Mb of kernel space to KERNEL_BASE
                    642:         * i.e. marks[KERNEL_START]
                    643:         */
1.1       reinoud   644:        for (page = 0; page < 16; page++) {
                    645:                addr  = (kernel_physical_start >> 20) + page;
                    646:                kpage = (marks[MARK_START]     >> 20) + page;
                    647:                initial_page_tables[kpage] = (addr << 20) | section;
1.22      bjh21     648:        }
1.1       reinoud   649: }
                    650:
                    651:
1.22      bjh21     652: void
                    653: add_pagetables_at_top(void)
                    654: {
1.1       reinoud   655:        int page;
                    656:        u_long src, dst, fragaddr;
                    657:
1.21      bjh21     658:        /* Special : destination must be on a 16 Kb boundary */
                    659:        /* get 4 pages on the top of the physical memory and copy PT's in it */
1.22      bjh21     660:        new_L1_pages_phys = top_physdram - 4 * nbpp;
1.1       reinoud   661:
1.21      bjh21     662:        /*
                    663:         * If the L1 page tables are not 16 kb aligned, adjust base
                    664:         * until it is
                    665:         */
1.22      bjh21     666:        while (new_L1_pages_phys & (16*1024-1))
1.6       reinoud   667:                new_L1_pages_phys -= nbpp;
1.21      bjh21     668:        if (new_L1_pages_phys & (16*1024-1))
                    669:                panic("Paranoia : L1 pages not on 16Kb boundary");
1.6       reinoud   670:
1.1       reinoud   671:        dst = new_L1_pages_phys;
1.22      bjh21     672:        src = (u_long)initial_page_tables;
1.1       reinoud   673:
                    674:        for (page = 0; page < 4; page++) {
                    675:                /* get a page for a fragment */
                    676:                fragaddr = get_relocated_page(dst, nbpp)->logical;
1.22      bjh21     677:                memcpy((void *)fragaddr, (void *)src, nbpp);
1.1       reinoud   678:
                    679:                src += nbpp;
                    680:                dst += nbpp;
1.22      bjh21     681:        }
1.1       reinoud   682: }
                    683:
                    684:
1.22      bjh21     685: void
                    686: add_initvectors(void)
                    687: {
1.1       reinoud   688:        u_long *pos;
                    689:        u_long  vectoraddr, count;
                    690:
                    691:        /* the top 1Mb of the physical DRAM pages is mapped at address 0 */
1.9       reinoud   692:        vectoraddr = get_relocated_page(top_1Mb_dram, nbpp)->logical;
1.1       reinoud   693:
                    694:        /* fill the vectors with `movs pc, lr' opcodes */
1.22      bjh21     695:        pos = (u_long *)vectoraddr; memset(pos, 0, nbpp);
1.1       reinoud   696:        for (count = 0; count < 128; count++) *pos++ = 0xE1B0F00E;
                    697: }
                    698:
1.29      bjh21     699: /*
                    700:  * Work out the display's vertical sync rate.  One might hope that there
                    701:  * would be a simpler way than by counting vsync interrupts for a second,
                    702:  * but if there is, I can't find it.
                    703:  */
                    704: static int
                    705: vsync_rate(void)
                    706: {
                    707:        uint8_t count0;
                    708:        unsigned int time0;
                    709:
                    710:        count0 = osbyte_read(osbyte_VAR_VSYNC_TIMER);
                    711:        time0 = os_read_monotonic_time();
                    712:        while (os_read_monotonic_time() - time0 < 100)
                    713:                continue;
                    714:        return (u_int8_t)(count0 - osbyte_read(osbyte_VAR_VSYNC_TIMER));
                    715: }
1.1       reinoud   716:
1.22      bjh21     717: void
                    718: create_configuration(int argc, char **argv, int start_args)
                    719: {
1.7       reinoud   720:        int   i, root_specified, id_low, id_high;
                    721:        char *pos;
1.22      bjh21     722:
1.1       reinoud   723:        bconfig_new_phys = kernel_free_vm_start - pv_offset;
                    724:        bconfig_page = get_relocated_page(bconfig_new_phys, nbpp);
1.22      bjh21     725:        bconfig = (struct bootconfig *)(bconfig_page->logical);
1.1       reinoud   726:        kernel_free_vm_start += nbpp;
                    727:
                    728:        /* get some miscelanious info for the bootblock */
1.28      christos  729:        os_readsysinfo_monitor_info(NULL, (int *)&monitor_type, (int *)&monitor_sync);
                    730:        os_readsysinfo_chip_presence((int *)&ioeb_flags, (int *)&superio_flags, (int *)&lcd_flags);
                    731:        os_readsysinfo_superio_features((int *)&superio_flags_basic,
                    732:            (int *)&superio_flags_extra);
1.2       reinoud   733:        os_readsysinfo_unique_id(&id_low, &id_high);
1.1       reinoud   734:
                    735:        /* fill in the bootconfig *bconfig structure : generic version II */
1.30.34.1! bouyer    736:        memset(bconfig, 0, sizeof(*bconfig));
1.16      reinoud   737:        bconfig->magic          = BOOTCONFIG_MAGIC;
                    738:        bconfig->version        = BOOTCONFIG_VERSION;
1.1       reinoud   739:        strcpy(bconfig->kernelname, booted_file);
1.2       reinoud   740:
1.21      bjh21     741:        /*
                    742:         * get the kernel base name and update the RiscOS name to a
                    743:         * Unix name
                    744:         */
1.16      reinoud   745:        i = strlen(booted_file);
1.22      bjh21     746:        while (i >= 0 && booted_file[i] != '.') i--;
1.16      reinoud   747:        if (i) {
                    748:                strcpy(bconfig->kernelname, "/");
                    749:                strcat(bconfig->kernelname, booted_file+i+1);
1.22      bjh21     750:        }
1.7       reinoud   751:
1.16      reinoud   752:        pos = bconfig->kernelname+1;
1.7       reinoud   753:        while (*pos) {
1.14      bjh21     754:                if (*pos == '/') *pos = '.';
1.7       reinoud   755:                pos++;
1.22      bjh21     756:        }
1.7       reinoud   757:
                    758:        /* set the machine_id */
1.2       reinoud   759:        memcpy(&(bconfig->machine_id), &id_low, 4);
1.1       reinoud   760:
1.7       reinoud   761:        /* check if the `root' is specified */
1.1       reinoud   762:        root_specified = 0;
                    763:        strcpy(bconfig->args, "");
                    764:        for (i = start_args; i < argc; i++) {
1.14      bjh21     765:                if (strncmp(argv[i], "root=",5) ==0) root_specified = 1;
1.1       reinoud   766:                strcat(bconfig->args, argv[i]);
1.22      bjh21     767:        }
1.1       reinoud   768:        if (!root_specified) {
                    769:                strcat(bconfig->args, "root=");
                    770:                strcat(bconfig->args, DEFAULT_ROOT);
1.22      bjh21     771:        }
1.1       reinoud   772:
1.7       reinoud   773:        /* mark kernel pointers */
1.1       reinoud   774:        bconfig->kernvirtualbase        = marks[MARK_START];
1.3       reinoud   775:        bconfig->kernphysicalbase       = kernel_physical_start;
1.21      bjh21     776:        bconfig->kernsize               = kernel_free_vm_start -
                    777:                                            marks[MARK_START];
1.1       reinoud   778:        bconfig->ksym_start             = marks[MARK_SYM];
                    779:        bconfig->ksym_end               = marks[MARK_SYM] + marks[MARK_NSYM];
                    780:
1.7       reinoud   781:        /* setup display info */
1.1       reinoud   782:        bconfig->display_phys           = videomem_start;
                    783:        bconfig->display_start          = videomem_start;
                    784:        bconfig->display_size           = display_size;
                    785:        bconfig->width                  = vdu_var(os_MODEVAR_XWIND_LIMIT);
                    786:        bconfig->height                 = vdu_var(os_MODEVAR_YWIND_LIMIT);
                    787:        bconfig->log2_bpp               = vdu_var(os_MODEVAR_LOG2_BPP);
1.29      bjh21     788:        bconfig->framerate              = vsync_rate();
1.1       reinoud   789:
1.7       reinoud   790:        /* fill in memory info */
1.1       reinoud   791:        bconfig->pagesize               = nbpp;
1.21      bjh21     792:        bconfig->drampages              = total_dram_pages +
                    793:                                            total_podram_pages; /* XXX */
1.1       reinoud   794:        bconfig->vrampages              = total_vram_pages;
1.21      bjh21     795:        bconfig->dramblocks             = dram_blocks + podram_blocks; /*XXX*/
1.1       reinoud   796:        bconfig->vramblocks             = vram_blocks;
                    797:
                    798:        for (i = 0; i < dram_blocks; i++) {
                    799:                bconfig->dram[i].address = DRAM_addr[i];
                    800:                bconfig->dram[i].pages   = DRAM_pages[i];
                    801:                bconfig->dram[i].flags   = PHYSMEM_TYPE_GENERIC;
1.22      bjh21     802:        }
1.1       reinoud   803:        for (; i < dram_blocks + podram_blocks; i++) {
                    804:                bconfig->dram[i].address = PODRAM_addr[i];
                    805:                bconfig->dram[i].pages   = PODRAM_pages[i];
                    806:                bconfig->dram[i].flags   = PHYSMEM_TYPE_PROCESSOR_ONLY;
1.22      bjh21     807:        }
1.1       reinoud   808:        for (i = 0; i < vram_blocks; i++) {
                    809:                bconfig->vram[i].address = VRAM_addr[i];
                    810:                bconfig->vram[i].pages   = VRAM_pages[i];
                    811:                bconfig->vram[i].flags   = PHYSMEM_TYPE_GENERIC;
1.22      bjh21     812:        }
1.1       reinoud   813: }
                    814:
                    815:
1.22      bjh21     816: int
                    817: main(int argc, char **argv)
                    818: {
1.1       reinoud   819:        int howto, start_args, ret;
                    820:
                    821:        printf("\n\n");
                    822:        printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
                    823:        printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
                    824:        printf(">> Booting NetBSD/acorn32 on a RiscPC/A7000/NC\n");
                    825:        printf("\n");
                    826:
                    827:        process_args(argc, argv, &howto, booted_file, &start_args);
                    828:
                    829:        printf("Booting %s (howto = 0x%x)\n", booted_file, howto);
                    830:
                    831:        init_datastructures();
                    832:        get_memory_configuration();
                    833:        get_memory_map();
                    834:
1.21      bjh21     835:        /*
                    836:         * point to the first free DRAM page guaranteed to be in
                    837:         * strict order up
                    838:         */
1.27      bjh21     839:        if (podram_blocks != 0) {
1.21      bjh21     840:                free_relocation_page =
                    841:                    mem_pages_info + first_mapped_PODRAM_page_index;
1.1       reinoud   842:                kernel_physical_start = PODRAM_addr[0];
                    843:        } else {
1.21      bjh21     844:                free_relocation_page =
                    845:                    mem_pages_info + first_mapped_DRAM_page_index;
1.1       reinoud   846:                kernel_physical_start = DRAM_addr[0];
1.22      bjh21     847:        }
1.1       reinoud   848:
                    849:        printf("\nLoading %s ", booted_file);
                    850:
                    851:        /* first count the kernel to get the markers */
                    852:        ret = loadfile(booted_file, marks, COUNT_KERNEL);
1.21      bjh21     853:        if (ret == -1) panic("Kernel load failed"); /* lie to the user ... */
1.1       reinoud   854:        close(ret);
                    855:
1.21      bjh21     856:        /*
                    857:         * calculate how much the difference is between physical and
                    858:         * virtual space for the kernel
                    859:         */
1.22      bjh21     860:        pv_offset = ((u_long)marks[MARK_START] - kernel_physical_start);
1.21      bjh21     861:        /* round on a page      */
                    862:        kernel_free_vm_start = (marks[MARK_END] + nbpp-1) & ~(nbpp-1);
1.1       reinoud   863:
1.15      reinoud   864:        /* we seem to be forced to clear the marks[] ? */
1.1       reinoud   865:        bzero(marks, sizeof(marks[MARK_MAX]));
                    866:
                    867:        /* really load it ! */
                    868:        ret = loadfile(booted_file, marks, LOAD_KERNEL);
                    869:        if (ret == -1) panic("Kernel load failed");
                    870:        close(ret);
                    871:
                    872:        /* finish off the relocation information */
                    873:        create_initial_page_tables();
                    874:        add_initvectors();
                    875:        add_pagetables_at_top();
                    876:        create_configuration(argc, argv, start_args);
                    877:
1.21      bjh21     878:        /*
                    879:         * done relocating and creating information, now update and
                    880:         * check the relocation mechanism
                    881:         */
1.1       reinoud   882:        prepare_and_check_relocation_system();
                    883:
                    884:        printf("\nStarting at 0x%lx\n", marks[MARK_ENTRY]);
1.21      bjh21     885:        printf("Will boot in a few secs due to relocation....\n"
                    886:            "bye bye from RISC OS!");
1.1       reinoud   887:
                    888:        /* dismount all filesystems */
                    889:        xosfscontrol_shutdown();
                    890:
                    891:        /* reset devices, well they try to anyway */
                    892:        service_pre_reset();
                    893:
                    894:        start_kernel(
                    895:                /* r0 relocation code page (V)  */ relocate_code_page->logical,
1.21      bjh21     896:                /* r1 relocation pv offset      */
                    897:                relocate_code_page->physical-relocate_code_page->logical,
1.22      bjh21     898:                /* r2 configuration structure   */ bconfig_new_phys,
1.21      bjh21     899:                /* r3 relocation table (P)      */
                    900:                relocate_table_pages->physical, /* one piece! */
1.1       reinoud   901:                /* r4 L1 page descriptor (P)    */ new_L1_pages_phys,
                    902:                /* r5 kernel entry point        */ marks[MARK_ENTRY]
                    903:        );
                    904:        return 0;
                    905: }
                    906:
                    907:
1.22      bjh21     908: ssize_t
                    909: boot32_read(int f, void *addr, size_t size)
                    910: {
1.30      christos  911:        void *fragaddr;
1.1       reinoud   912:        size_t fragsize;
                    913:        ssize_t bytes_read, total;
                    914:
                    915:        /* printf("read at %p for %ld bytes\n", addr, size); */
                    916:        total = 0;
                    917:        while (size > 0) {
1.21      bjh21     918:                fragsize = nbpp;                /* select one page      */
                    919:                if (size < nbpp) fragsize = size;/* clip to size left   */
1.1       reinoud   920:
                    921:                /* get a page for a fragment */
1.30      christos  922:                fragaddr = (void *)get_relocated_page((u_long) addr -
1.21      bjh21     923:                    pv_offset, fragsize)->logical;
1.1       reinoud   924:
                    925:                bytes_read = read(f, fragaddr, fragsize);
1.21      bjh21     926:                if (bytes_read < 0) return bytes_read;  /* error!       */
                    927:                total += bytes_read;            /* account read bytes   */
1.1       reinoud   928:
1.21      bjh21     929:                if (bytes_read < fragsize)
                    930:                        return total;           /* does this happen?    */
1.1       reinoud   931:
1.21      bjh21     932:                size -= fragsize;               /* advance              */
1.1       reinoud   933:                addr += fragsize;
1.22      bjh21     934:        }
1.1       reinoud   935:        return total;
                    936: }
                    937:
                    938:
1.22      bjh21     939: void *
                    940: boot32_memcpy(void *dst, const void *src, size_t size)
                    941: {
1.30      christos  942:        void *fragaddr;
1.1       reinoud   943:        size_t fragsize;
                    944:
                    945:        /* printf("memcpy to %p from %p for %ld bytes\n", dst, src, size); */
                    946:        while (size > 0) {
1.21      bjh21     947:                fragsize = nbpp;                /* select one page      */
                    948:                if (size < nbpp) fragsize = size;/* clip to size left   */
1.1       reinoud   949:
                    950:                /* get a page for a fragment */
1.30      christos  951:                fragaddr = (void *)get_relocated_page((u_long) dst -
1.21      bjh21     952:                    pv_offset, fragsize)->logical;
1.1       reinoud   953:                memcpy(fragaddr, src, size);
                    954:
1.21      bjh21     955:                src += fragsize;                /* account copy         */
1.1       reinoud   956:                dst += fragsize;
                    957:                size-= fragsize;
1.22      bjh21     958:        }
1.1       reinoud   959:        return dst;
1.22      bjh21     960: }
1.1       reinoud   961:
                    962:
1.22      bjh21     963: void *
                    964: boot32_memset(void *dst, int c, size_t size)
                    965: {
1.30      christos  966:        void *fragaddr;
1.1       reinoud   967:        size_t fragsize;
                    968:
                    969:        /* printf("memset %p for %ld bytes with %d\n", dst, size, c); */
                    970:        while (size > 0) {
1.21      bjh21     971:                fragsize = nbpp;                /* select one page      */
                    972:                if (size < nbpp) fragsize = size;/* clip to size left   */
1.1       reinoud   973:
                    974:                /* get a page for a fragment */
1.30      christos  975:                fragaddr = (void *)get_relocated_page((u_long)dst - pv_offset,
1.22      bjh21     976:                    fragsize)->logical;
1.1       reinoud   977:                memset(fragaddr, c, fragsize);
                    978:
1.21      bjh21     979:                dst += fragsize;                /* account memsetting   */
1.1       reinoud   980:                size-= fragsize;
                    981:
1.22      bjh21     982:        }
1.1       reinoud   983:        return dst;
                    984: }
                    985:
                    986:
1.18      abs       987: /* We can rely on the fact that two entries never have identical ->physical */
1.22      bjh21     988: int
                    989: page_info_cmp(const void *a, const void *b)
                    990: {
                    991:
1.18      abs       992:        return (((struct page_info *)a)->physical <
                    993:            ((struct page_info *)b)->physical) ? -1 : 1;
1.1       reinoud   994: }
                    995:
1.22      bjh21     996: struct page_info *
                    997: get_relocated_page(u_long destination, int size)
                    998: {
1.1       reinoud   999:        struct page_info *page;
                   1000:
                   1001:        /* get a page for a fragment */
                   1002:        page = free_relocation_page;
1.17      gavan    1003:        if (free_relocation_page->pagenumber < 0) panic("\n\nOut of pages");
1.1       reinoud  1004:        reloc_entries++;
1.21      bjh21    1005:        if (reloc_entries >= MAX_RELOCPAGES)
                   1006:                panic("\n\nToo many relocations! What are you loading ??");
1.1       reinoud  1007:
                   1008:        /* record the relocation */
                   1009:        *reloc_pos++ = free_relocation_page->physical;
                   1010:        *reloc_pos++ = destination;
                   1011:        *reloc_pos++ = size;
1.21      bjh21    1012:        free_relocation_page++;                 /* advance              */
1.1       reinoud  1013:
                   1014:        return page;
                   1015: }
                   1016:
                   1017:
1.22      bjh21    1018: int
                   1019: vdu_var(int var)
                   1020: {
1.1       reinoud  1021:        int varlist[2], vallist[2];
                   1022:
                   1023:        varlist[0] = var;
                   1024:        varlist[1] = -1;
                   1025:        os_read_vdu_variables(varlist, vallist);
                   1026:        return vallist[0];
                   1027: }
                   1028:
                   1029:
1.22      bjh21    1030: void
                   1031: twirl(void)
                   1032: {
                   1033:
1.1       reinoud  1034:        printf("%c%c", "|/-\\"[(int) twirl_cnt], 8);
                   1035:        twirl_cnt++;
                   1036:        twirl_cnt &= 3;
                   1037: }
                   1038:
                   1039:
1.22      bjh21    1040: void
                   1041: process_args(int argc, char **argv, int *howto, char *file, int *start_args)
                   1042: {
1.1       reinoud  1043:        int i, j;
                   1044:        static char filename[80];
                   1045:
                   1046:        *howto = 0;
                   1047:        *file = NULL; *start_args = 1;
                   1048:        for (i = 1; i < argc; i++) {
                   1049:                if (argv[i][0] == '-')
                   1050:                        for (j = 1; argv[i][j]; j++)
                   1051:                                BOOT_FLAG(argv[i][j], *howto);
                   1052:                else {
                   1053:                        if (*file)
                   1054:                                *start_args = i;
                   1055:                        else {
                   1056:                                strcpy(file, argv[i]);
                   1057:                                *start_args = i+1;
1.22      bjh21    1058:                        }
1.1       reinoud  1059:                        break;
1.22      bjh21    1060:                }
                   1061:        }
1.1       reinoud  1062:        if (*file == NULL) {
                   1063:                if (*howto & RB_ASKNAME) {
                   1064:                        printf("boot: ");
                   1065:                        gets(filename);
                   1066:                        strcpy(file, filename);
                   1067:                } else
                   1068:                        strcpy(file, "netbsd");
1.22      bjh21    1069:        }
1.1       reinoud  1070: }
1.24      bjh21    1071:
                   1072:
                   1073: char *
                   1074: sprint0(int width, char prefix, char base, int value)
                   1075: {
                   1076:        static char format[50], scrap[50];
                   1077:        char *pos;
                   1078:        int length;
                   1079:
                   1080:        for (pos = format, length = 0; length<width; length++) *pos++ = prefix;
                   1081:        *pos++ = '%';
                   1082:        *pos++ = base;
                   1083:        *pos++ = (char) 0;
                   1084:
                   1085:        sprintf(scrap, format, value);
                   1086:        length = strlen(scrap);
                   1087:
                   1088:        return scrap+length-width;
                   1089: }
                   1090:

CVSweb <webmaster@jp.NetBSD.org>