Changeset 965dc18 in mainline for boot/arch/sparc64/loader


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/arch/sparc64/loader
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.