Changeset 965dc18 in mainline for boot


Ignore:
Timestamp:
2008-12-05T19:59:03Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
49093a4
Parents:
0258e67
Message:

Merge sparc branch to trunk.

Location:
boot
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • boot/arch/ppc64/Makefile.inc

    r0258e67 r965dc18  
    2727#
    2828
     29DEFS += -DOPEN_BOOT
     30
    2931build: $(BASE)/image.boot
    3032
     
    3638
    3739arch/$(ARCH)/loader/image.boot:
    38         make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
     40        make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)"
    3941
    4042clean: generic_clean
  • boot/arch/sparc64/Makefile.inc

    r0258e67 r965dc18  
    2929TMP = distroot
    3030
     31ifeq ($(CONFIG_AOUT_ISOFS_B),n)
     32        SILO_PACKAGE=silo.patched.tar.gz
     33endif
     34
     35ifeq ($(CONFIG_AOUT_ISOFS_B),y)
     36        SILO_PACKAGE=silo.tar.gz
     37endif
     38
    3139build: $(BASE)/image.iso
    3240
     
    4048        mkdir -p $(TMP)/boot
    4149        mkdir -p $(TMP)/HelenOS
    42         cat arch/$(ARCH)/silo/silo.tar.gz | (cd $(TMP)/boot; tar xvfz -)
     50        cat arch/$(ARCH)/silo/$(SILO_PACKAGE) | (cd $(TMP)/boot; tar xvfz -)
    4351        cp arch/$(ARCH)/silo/README arch/$(ARCH)/silo/COPYING $(TMP)/boot
    4452        cat arch/$(ARCH)/silo/silo.conf | $(SILO_CONF_FILTER) >$(TMP)/boot/silo.conf
  • boot/arch/sparc64/loader/asm.S

    r0258e67 r965dc18  
    106106         * 2. Invalidate I-cache.
    107107         * 3. Flush instruction pipeline.
    108          */
    109         call    icache_flush
    110         membar  #StoreStore
     108         */
     109
     110        /*
     111         * US3 processors have a write-invalidate cache, so explicitly
     112         * invalidating it is not required. Whether to invalidate I-cache
     113         * or not is decided according to the value of the global
     114         * "subarchitecture" variable (set in the bootstrap).
     115         */
     116        set subarchitecture, %g2
     117        ldub [%g2], %g2
     118        cmp %g2, 3
     119        be 1f
     120        nop
     1210:
     122        call icache_flush
     123        nop
     1241:
     125        membar #StoreStore
     126       
     127        /*
     128         * Flush the instruction pipeline.
     129         */
    111130        flush   %i7
    112131
     
    135154        ! SF Erratum #51
    136155        nop
    137 
    138156.global ofw
    139157ofw:
  • boot/arch/sparc64/loader/main.c

    r0258e67 r965dc18  
    4040
    4141bootinfo_t bootinfo;
     42
    4243component_t components[COMPONENTS];
    4344
     
    5556        char *timestamp = "";
    5657#endif
     58
     59/** UltraSPARC subarchitecture - 1 for US, 3 for US3 */
     60uint8_t subarchitecture;
     61
     62/**
     63 * mask of the MID field inside the ICBUS_CONFIG register shifted by
     64 * MID_SHIFT bits to the right
     65 */
     66uint16_t mid_mask;
    5767
    5868/** Print version information. */
     
    6474}
    6575
     76/* the lowest ID (read from the VER register) of some US3 CPU model */
     77#define FIRST_US3_CPU   0x14
     78
     79/* the greatest ID (read from the VER register) of some US3 CPU model */
     80#define LAST_US3_CPU    0x19
     81
     82/* UltraSPARC IIIi processor implementation code */
     83#define US_IIIi_CODE    0x15
     84
     85/**
     86 * Sets the global variables "subarchitecture" and "mid_mask" to
     87 * correct values.
     88 */
     89static void detect_subarchitecture(void)
     90{
     91        uint64_t v;
     92        asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
     93       
     94        v = (v << 16) >> 48;
     95        if ((v >= FIRST_US3_CPU) && (v <= LAST_US3_CPU)) {
     96                subarchitecture = SUBARCH_US3;
     97                if (v == US_IIIi_CODE)
     98                        mid_mask = (1 << 5) - 1;
     99                else
     100                        mid_mask = (1 << 10) - 1;
     101        } else if (v < FIRST_US3_CPU) {
     102                subarchitecture = SUBARCH_US;
     103                mid_mask = (1 << 5) - 1;
     104        } else {
     105                printf("\nThis CPU is not supported by HelenOS.");
     106        }
     107}
     108
    66109void bootstrap(void)
    67110{
     
    73116        version_print();
    74117       
     118        detect_subarchitecture();
    75119        init_components(components);
    76120
     
    84128                halt();
    85129        }
    86        
     130
    87131        if (bootinfo.memmap.total == 0) {
    88132                printf("Error: no memory detected, halting.\n");
  • boot/arch/sparc64/loader/main.h

    r0258e67 r965dc18  
    4242#define AP_PROCESSOR    0
    4343
     44#define SUBARCH_US      1
     45#define SUBARCH_US3     3
     46
    4447typedef struct {
    4548        void *addr;
  • boot/arch/sparc64/loader/ofwarch.c

    r0258e67 r965dc18  
    4141#include "asm.h"
    4242
     43/* these tho variables will be set by the detect_subarchitecture function */
     44extern uint8_t subarchitecture;
     45extern uint16_t mid_mask;
     46
    4347void write(const char *str, const int len)
    4448{
     
    5761}
    5862
    59 int ofw_cpu(void)
     63/**
     64 * Starts all CPUs represented by following siblings of the given node,
     65 * except for the current CPU.
     66 *
     67 * @param child         The first child of the OFW tree node whose children
     68 *                      represent CPUs to be woken up.
     69 * @param current_mid   MID of the current CPU, the current CPU will
     70 *                      (of course) not be woken up.
     71 * @return              Number of CPUs which have the same parent node as
     72 *                      "child".
     73 */
     74static int wake_cpus_in_node(phandle child, uint64_t current_mid)
    6075{
     76        int cpus;
    6177        char type_name[BUF_SIZE];
    62 
    63         phandle node;
    64         node = ofw_get_child_node(ofw_root);
    65         if (node == 0 || node == -1) {
    66                 printf("Could not find any child nodes of the root node.\n");
    67                 return 0;
    68         }
    6978       
    70         uint64_t current_mid;
    71        
    72         asm volatile ("ldxa [%1] %2, %0\n"
    73             : "=r" (current_mid)
    74             : "r" (0), "i" (ASI_UPA_CONFIG));
    75         current_mid >>= UPA_CONFIG_MID_SHIFT;
    76         current_mid &= UPA_CONFIG_MID_MASK;
    77 
    78         int cpus;
    79        
    80         for (cpus = 0; node != 0 && node != -1; node = ofw_get_peer_node(node),
    81             cpus++) {
    82                 if (ofw_get_property(node, "device_type", type_name,
     79        for (cpus = 0; child != 0 && child != -1;
     80            child = ofw_get_peer_node(child), cpus++) {
     81                if (ofw_get_property(child, "device_type", type_name,
    8382                    sizeof(type_name)) > 0) {
    8483                        if (strcmp(type_name, "cpu") == 0) {
    8584                                uint32_t mid;
    8685                               
    87                                 if (ofw_get_property(node, "upa-portid", &mid,
    88                                     sizeof(mid)) <= 0)
     86                                /*
     87                                 * "upa-portid" for US, "portid" for US-III,
     88                                 * "cpuid" for US-IV
     89                                 */
     90                                if (ofw_get_property(
     91                                    child, "upa-portid",
     92                                    &mid, sizeof(mid)) <= 0
     93                                    && ofw_get_property(child, "portid",
     94                                    &mid, sizeof(mid)) <= 0
     95                                    && ofw_get_property(child, "cpuid",
     96                                    &mid, sizeof(mid)) <= 0)
    8997                                        continue;
    9098                                       
     
    94102                                         */
    95103                                        (void) ofw_call("SUNW,start-cpu", 3, 1,
    96                                             NULL, node, KERNEL_VIRTUAL_ADDRESS,
     104                                            NULL, child, KERNEL_VIRTUAL_ADDRESS,
    97105                                            bootinfo.physmem_start |
    98106                                            AP_PROCESSOR);
     
    105113}
    106114
     115/**
     116 * Finds out the current CPU's MID and wakes up all AP processors.
     117 */
     118int ofw_cpu(void)
     119{
     120        int cpus;
     121        phandle node;
     122        phandle subnode;
     123        phandle cpus_parent;
     124        phandle cmp;
     125        char name[BUF_SIZE];
     126
     127        /* get the current CPU MID */
     128        uint64_t current_mid;
     129       
     130        asm volatile ("ldxa [%1] %2, %0\n"
     131            : "=r" (current_mid)
     132            : "r" (0), "i" (ASI_ICBUS_CONFIG));
     133        current_mid >>= ICBUS_CONFIG_MID_SHIFT;
     134
     135        current_mid &= mid_mask;
     136
     137        /* wake up CPUs */
     138       
     139        cpus_parent = ofw_find_device("/ssm@0,0");
     140        if (cpus_parent == 0 || cpus_parent == -1) {
     141                cpus_parent = ofw_find_device("/");
     142        }
     143
     144        node = ofw_get_child_node(cpus_parent);
     145        cpus = wake_cpus_in_node(node, current_mid);
     146        while (node != 0 && node != -1) {
     147                if (ofw_get_property(node, "name", name,
     148                        sizeof(name)) > 0) {
     149                        if (strcmp(name, "cmp") == 0) {
     150                                subnode = ofw_get_child_node(node);
     151                                cpus += wake_cpus_in_node(subnode,
     152                                        current_mid);
     153                        }
     154                }
     155                node = ofw_get_peer_node(node);
     156        }
     157       
     158        return cpus;
     159       
     160}
     161
    107162/** Get physical memory starting address.
    108163 *
    109  * @param start Pointer to variable where the physical memory starting
    110  *              address will be stored.
     164 * @param start         Pointer to variable where the physical memory starting
     165 *                      address will be stored.
    111166 *
    112  * @return Non-zero on succes, zero on failure.
     167 * @return              Non-zero on succes, zero on failure.
    113168 */
    114169int ofw_get_physmem_start(uintptr_t *start)
  • boot/arch/sparc64/loader/register.h

    r0258e67 r965dc18  
    3434#define PSTATE_AM_BIT   8
    3535
    36 #define ASI_UPA_CONFIG          0x4a
    37 #define UPA_CONFIG_MID_SHIFT    17
    38 #define UPA_CONFIG_MID_MASK     0x1f
     36#define ASI_ICBUS_CONFIG                0x4a
     37#define ICBUS_CONFIG_MID_SHIFT          17
    3938
    4039#endif
  • boot/boot.config

    r0258e67 r965dc18  
    8484! RDFMT (choice)
    8585
     86# Preserve A.OUT header in isofs.b
     87! [ARCH=sparc64] CONFIG_AOUT_ISOFS_B (y/n)
     88
    8689# External ramdisk
    8790! [ARCH=sparc64] CONFIG_RD_EXTERNAL (y/n)
  • boot/genarch/balloc.h

    r0258e67 r965dc18  
    3232#include <types.h>
    3333
    34 #define BALLOC_MAX_SIZE         (1024 * 1024)
     34#define BALLOC_MAX_SIZE         (128 * 1024)
    3535
    3636typedef struct {
  • boot/genarch/ofw.c

    r0258e67 r965dc18  
    4949                halt();
    5050       
    51         if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0)
     51        if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout,
     52            sizeof(ofw_stdout)) <= 0)
    5253                ofw_stdout = 0;
    5354       
     
    5859        }
    5960       
    60         if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, sizeof(ofw_mmu)) <= 0) {
     61        if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu,
     62            sizeof(ofw_mmu)) <= 0) {
    6163                puts("\r\nError: Unable to get mmu property, halted.\r\n");
    6264                halt();
    6365        }
    64         if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop, sizeof(ofw_memory_prop)) <= 0) {
     66        if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop,
     67            sizeof(ofw_memory_prop)) <= 0) {
    6568                puts("\r\nError: Unable to get memory property, halted.\r\n");
    6669                halt();
     
    8285/** Perform a call to OpenFirmware client interface.
    8386 *
    84  * @param service String identifying the service requested.
    85  * @param nargs Number of input arguments.
    86  * @param nret Number of output arguments. This includes the return value.
    87  * @param rets Buffer for output arguments or NULL. The buffer must accommodate nret - 1 items.
    88  *
    89  * @return Return value returned by the client interface.
     87 * @param service       String identifying the service requested.
     88 * @param nargs         Number of input arguments.
     89 * @param nret          Number of output arguments. This includes the return
     90 *                      value.
     91 * @param rets          Buffer for output arguments or NULL. The buffer must
     92 *                      accommodate nret - 1 items.
     93 *
     94 * @return              Return value returned by the client interface.
    9095 */
    91 unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...)
     96unsigned long
     97ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets,
     98    ...)
    9299{
    93100        va_list list;
     
    120127}
    121128
    122 int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen)
     129int
     130ofw_get_property(const phandle device, const char *name, void *buf,
     131    const int buflen)
    123132{
    124133        return ofw_call("getprop", 4, 1, NULL, device, name, buf, buflen);
     
    145154       
    146155        if (ofw_get_property(device, "#address-cells", &ret, sizeof(ret)) <= 0)
    147                 if (ofw_get_property(ofw_root, "#address-cells", &ret, sizeof(ret)) <= 0)
     156                if (ofw_get_property(ofw_root, "#address-cells", &ret,
     157                    sizeof(ret)) <= 0)
    148158                        ret = OFW_ADDRESS_CELLS;
    149159       
     
    157167       
    158168        if (ofw_get_property(device, "#size-cells", &ret, sizeof(ret)) <= 0)
    159                 if (ofw_get_property(ofw_root, "#size-cells", &ret, sizeof(ret)) <= 0)
     169                if (ofw_get_property(ofw_root, "#size-cells", &ret,
     170                    sizeof(ret)) <= 0)
    160171                        ret = OFW_SIZE_CELLS;
    161172       
     
    193204        int shift;
    194205
    195         if (ofw_call("call-method", 3, 5, result, "translate", ofw_mmu, virt) != 0) {
     206        if (ofw_call("call-method", 3, 5, result, "translate", ofw_mmu,
     207            virt) != 0) {
    196208                puts("Error: MMU method translate() failed, halting.\n");
    197209                halt();
     
    213225        ofw_arg_t retaddr;
    214226
    215         if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len, virt) != 0) {
     227        if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len,
     228            virt) != 0) {
    216229                puts("Error: MMU method claim() failed, halting.\n");
    217230                halt();
     
    270283        }
    271284
    272         return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size, virt,
    273             phys_hi, phys_lo);
     285        return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size,
     286            virt, phys_hi, phys_lo);
    274287}
    275288
     
    282295int ofw_memmap(memmap_t *map)
    283296{
    284         unsigned int ac = ofw_get_address_cells(ofw_memory);
    285         unsigned int sc = ofw_get_size_cells(ofw_memory);
    286 
    287         uint32_t buf[((ac + sc) * MEMMAP_MAX_RECORDS)];
     297        unsigned int ac = ofw_get_address_cells(ofw_memory) /
     298            (sizeof(uintptr_t) / sizeof(uint32_t));
     299        unsigned int sc = ofw_get_size_cells(ofw_memory) /
     300            (sizeof(uintptr_t) / sizeof(uint32_t));
     301        printf("address cells: %d, size cells: %d. ", ac, sc);
     302
     303        uintptr_t buf[((ac + sc) * MEMMAP_MAX_RECORDS)];
    288304        int ret = ofw_get_property(ofw_memory, "reg", buf, sizeof(buf));
    289305        if (ret <= 0)           /* ret is the number of written bytes */
     
    293309        map->total = 0;
    294310        map->count = 0;
    295         for (pos = 0; (pos < ret / sizeof(uint32_t)) &&
     311        for (pos = 0; (pos < ret / sizeof(uintptr_t)) &&
    296312            (map->count < MEMMAP_MAX_RECORDS); pos += ac + sc) {
    297                 void * start = (void *) ((uintptr_t) buf[pos + ac - 1]);
     313                void *start = (void *) (buf[pos + ac - 1]);
    298314                unsigned int size = buf[pos + ac + sc - 1];
    299                
     315
     316                /*
     317                 * This is a hot fix of the issue which occurs on machines
     318                 * where there are holes in the physical memory (such as
     319                 * SunBlade 1500). Should we detect a hole in the physical
     320                 * memory, we will ignore any memory detected behind
     321                 * the hole and pretend the hole does not exist.
     322                 */
     323                if ((map->count > 0) && (map->zones[map->count - 1].start +
     324                    map->zones[map->count - 1].size < start))
     325                        break;
     326
    300327                if (size > 0) {
    301328                        map->zones[map->count].start = start;
     
    309336}
    310337
    311 
    312338int ofw_screen(screen_t *screen)
    313339{
     
    315341        uint32_t virtaddr;
    316342       
    317         if (ofw_get_property(ofw_aliases, "screen", device_name, sizeof(device_name)) <= 0)
     343        if (ofw_get_property(ofw_aliases, "screen", device_name,
     344            sizeof(device_name)) <= 0)
    318345                return false;
    319346       
     
    322349                return false;
    323350       
    324         if (ofw_get_property(device, "address", &virtaddr, sizeof(virtaddr)) <= 0)
     351        if (ofw_get_property(device, "address", &virtaddr,
     352            sizeof(virtaddr)) <= 0)
    325353                return false;
    326354
    327355        screen->addr = (void *) ((uintptr_t) virtaddr);
    328356
    329         if (ofw_get_property(device, "width", &screen->width, sizeof(screen->width)) <= 0)
    330                 return false;
    331        
    332         if (ofw_get_property(device, "height", &screen->height, sizeof(screen->height)) <= 0)
    333                 return false;
    334        
    335         if (ofw_get_property(device, "depth", &screen->bpp, sizeof(screen->bpp)) <= 0)
    336                 return false;
    337        
    338         if (ofw_get_property(device, "linebytes", &screen->scanline, sizeof(screen->scanline)) <= 0)
     357        if (ofw_get_property(device, "width", &screen->width,
     358            sizeof(screen->width)) <= 0)
     359                return false;
     360       
     361        if (ofw_get_property(device, "height", &screen->height,
     362            sizeof(screen->height)) <= 0)
     363                return false;
     364       
     365        if (ofw_get_property(device, "depth", &screen->bpp,
     366            sizeof(screen->bpp)) <= 0)
     367                return false;
     368       
     369        if (ofw_get_property(device, "linebytes", &screen->scanline,
     370            sizeof(screen->scanline)) <= 0)
    339371                return false;
    340372       
  • boot/genarch/ofw_tree.c

    r0258e67 r965dc18  
    121121                memcpy(current_node->da_name, &path[i], len);
    122122                current_node->da_name[len] = '\0';
    123        
    124123       
    125124                /*
     
    220219{
    221220        ofw_tree_node_t *root;
     221        phandle ssm_node;
     222        ofw_tree_node_t *ssm;
    222223       
    223224        root = ofw_tree_node_alloc();
    224225        if (root)
    225226                ofw_tree_node_process(root, NULL, ofw_root);
     227
     228        /*
     229         * The firmware client interface does not automatically include the
     230         * "ssm" node in the list of children of "/". A nasty yet working
     231         * solution is to explicitly stick "ssm" to the OFW tree.
     232         */
     233        ssm_node = ofw_find_device("/ssm@0,0");
     234        if (ssm_node != -1) {
     235                ssm = ofw_tree_node_alloc();
     236                if (ssm) {
     237                        ofw_tree_node_process(
     238                                ssm, root, ofw_find_device("/ssm@0,0"));
     239                        ssm->peer = root->child;
     240                        root->child = ssm;
     241                }
     242        }
    226243       
    227244        return root;
Note: See TracChangeset for help on using the changeset viewer.