Changeset bfd7aac in mainline for boot/arch/sparc64/loader/main.c


Ignore:
Timestamp:
2010-02-17T19:19:08Z (14 years ago)
Author:
Lukas Mejdrech <lukasmejdrech@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1e2e0c1e
Parents:
01a9ef5 (diff), b8da2a3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • boot/arch/sparc64/loader/main.c

    r01a9ef5 rbfd7aac  
    5757#endif
    5858
    59 /** UltraSPARC subarchitecture - 1 for US, 3 for US3 */
    60 static uint8_t subarchitecture;
     59/** UltraSPARC subarchitecture - 1 for US, 3 for US3, 0 for other */
     60static uint8_t subarchitecture = 0;
    6161
    6262/**
     
    6969static void version_print(void)
    7070{
     71       
    7172        printf("HelenOS SPARC64 Bootloader\nRelease %s%s%s\n"
    7273            "Copyright (c) 2006 HelenOS project\n",
     
    8384#define US_IIIi_CODE   0x15
    8485
    85 /**
    86  * Sets the global variables "subarchitecture" and "mid_mask" to
     86/* max. length of the "compatible" property of the root node */
     87#define COMPATIBLE_PROP_MAXLEN  64
     88
     89/*
     90 * HelenOS bootloader will use these constants to distinguish particular
     91 * UltraSPARC architectures
     92 */
     93#define COMPATIBLE_SUN4U        10
     94#define COMPATIBLE_SUN4V        20
     95
     96/** US architecture. COMPATIBLE_SUN4U for sun4v, COMPATIBLE_SUN4V for sun4u */
     97static uint8_t architecture;
     98
     99/**
     100 * Detects the UltraSPARC architecture (sun4u and sun4v currently supported)
     101 * by inspecting the property called "compatible" in the OBP root node.
     102 */
     103static void detect_architecture(void)
     104{
     105        phandle root = ofw_find_device("/");
     106        char compatible[COMPATIBLE_PROP_MAXLEN];
     107
     108        if (ofw_get_property(root, "compatible", compatible,
     109                        COMPATIBLE_PROP_MAXLEN) <= 0) {
     110                printf("Unable to determine architecture, default: sun4u.\n");
     111                architecture = COMPATIBLE_SUN4U;
     112                return;
     113        }
     114
     115        if (strcmp(compatible, "sun4v") == 0) {
     116                architecture = COMPATIBLE_SUN4V;
     117        } else {
     118                /*
     119                 * As not all sun4u machines have "sun4u" in their "compatible"
     120                 * OBP property (e.g. Serengeti's OBP "compatible" property is
     121                 * "SUNW,Serengeti"), we will by default fallback to sun4u if
     122                 * an unknown value of the "compatible" property is encountered.
     123                 */
     124                architecture = COMPATIBLE_SUN4U;
     125        }
     126}
     127
     128
     129/**
     130 * Detects the subarchitecture (US, US3) of the sun4u
     131 * processor. Sets the global variables "subarchitecture" and "mid_mask" to
    87132 * correct values.
    88133 */
     
    109154}
    110155
     156/**
     157 * Performs sun4u-specific initialization. The components are expected
     158 * to be already copied and boot allocator initialized.
     159 *
     160 * @param base  kernel base virtual address
     161 * @param top   virtual address above which the boot allocator
     162 *              can make allocations
     163 */
     164static void bootstrap_sun4u(void *base, unsigned int top)
     165{
     166        void *balloc_base;
     167        /*
     168         * Claim and map the physical memory for the boot allocator.
     169         * Initialize the boot allocator.
     170         */
     171        balloc_base = base + ALIGN_UP(top, PAGE_SIZE);
     172        (void) ofw_claim_phys(bootinfo.physmem_start + balloc_base,
     173            BALLOC_MAX_SIZE);
     174        (void) ofw_map(bootinfo.physmem_start + balloc_base, balloc_base,
     175            BALLOC_MAX_SIZE, -1);
     176        balloc_init(&bootinfo.ballocs, (uintptr_t) balloc_base,
     177            (uintptr_t) balloc_base);
     178       
     179        printf("Setting up screens...");
     180        ofw_setup_screens();
     181        printf("done.\n");
     182       
     183        printf("Canonizing OpenFirmware device tree...");
     184        bootinfo.ofw_root = ofw_tree_build();
     185        printf("done.\n");
     186       
     187#ifdef CONFIG_AP
     188        printf("Checking for secondary processors...");
     189        if (!ofw_cpu(mid_mask, bootinfo.physmem_start))
     190                printf("Error: unable to get CPU properties\n");
     191        printf("done.\n");
     192#endif
     193
     194}
     195
     196/**
     197 *  * Performs sun4v-specific initialization. The components are expected
     198 *   * to be already copied and boot allocator initialized.
     199 *    */
     200static void bootstrap_sun4v(void)
     201{
     202        /*
     203         * When SILO booted, the OBP had established a virtual to physical
     204         * memory mapping. This mapping is not an identity (because the
     205         * physical memory starts on non-zero address) - this is not
     206         * surprising. But! The mapping even does not map virtual address
     207         * 0 onto the starting address of the physical memory, but onto an
     208         * address which is 0x400000 bytes higher. The reason is that the
     209         * OBP had already used the memory just at the beginning of the
     210         * physical memory, so that memory cannot be used by SILO (nor
     211         * bootloader). As for now, we solve it by a nasty workaround:
     212         * we pretend that the physical memory starts 0x400000 bytes further
     213         * than it actually does (and hence pretend that the physical memory
     214         * is 0x400000 bytes smaller). Of course, the value 0x400000 will most
     215         * probably depend on the machine and OBP version (the workaround now
     216         * works on Simics). A solution would be to inspect the "available"
     217         * property of the "/memory" node to find out which parts of memory
     218         * are used by OBP and redesign the algorithm of copying
     219         * kernel/init tasks/ramdisk from the bootable image to memory
     220         * (which we must do anyway because of issues with claiming the memory
     221         * on Serengeti).
     222         */
     223        bootinfo.physmem_start += 0x400000;
     224        bootinfo.memmap.zones[0].start += 0x400000;
     225        bootinfo.memmap.zones[0].size -= 0x400000;
     226        printf("The sun4v init finished.");
     227}
     228
     229
    111230void bootstrap(void)
    112231{
    113232        void *base = (void *) KERNEL_VIRTUAL_ADDRESS;
    114         void *balloc_base;
    115233        unsigned int top = 0;
    116234        unsigned int i;
    117235        unsigned int j;
    118236       
    119         version_print();
    120        
    121         detect_subarchitecture();
     237        detect_architecture();
    122238        init_components(components);
    123239       
     
    260376        printf("done.\n");
    261377       
    262         /*
    263          * Claim and map the physical memory for the boot allocator.
    264          * Initialize the boot allocator.
    265          */
    266         balloc_base = base + ALIGN_UP(top, PAGE_SIZE);
    267         (void) ofw_claim_phys(bootinfo.physmem_start + balloc_base,
    268             BALLOC_MAX_SIZE);
    269         (void) ofw_map(bootinfo.physmem_start + balloc_base, balloc_base,
    270             BALLOC_MAX_SIZE, -1);
    271         balloc_init(&bootinfo.ballocs, (uintptr_t) balloc_base,
    272             (uintptr_t) balloc_base);
    273        
    274         printf("Setting up screens...");
    275         ofw_setup_screens();
    276         printf("done.\n");
    277        
    278         printf("Canonizing OpenFirmware device tree...");
    279         bootinfo.ofw_root = ofw_tree_build();
    280         printf("done.\n");
    281        
    282 #ifdef CONFIG_AP
    283         printf("Checking for secondary processors...");
    284         if (!ofw_cpu(mid_mask, bootinfo.physmem_start))
    285                 printf("Error: unable to get CPU properties\n");
    286         printf("done.\n");
    287 #endif
     378        /* perform architecture-specific initialization */
     379        if (architecture == COMPATIBLE_SUN4U) {
     380                bootstrap_sun4u(base, top);
     381        } else if (architecture == COMPATIBLE_SUN4V) {
     382                bootstrap_sun4v();
     383        } else {
     384                printf("Unknown architecture.\n");
     385                halt();
     386        }
    288387       
    289388        printf("Booting the kernel...\n");
Note: See TracChangeset for help on using the changeset viewer.