Changeset a9ac978 in mainline


Ignore:
Timestamp:
2006-09-27T20:11:34Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
00b38a3
Parents:
86b31ba9
Message:

SMP stuff for sparc64.
Almost complete except for IPIs.
The absence of IPI support deadlocks
the kernel when more CPUs are configured.

Files:
2 added
14 edited

Legend:

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

    r86b31ba9 ra9ac978  
    3636#include <printf.h>
    3737#include <string.h>
     38#include <register.h>
    3839#include "main.h"
    3940
     
    5455}
    5556
    56 
    57 #define ASI_UPA_CONFIG          0x4a
    58 #define UPA_CONFIG_MID_SHIFT    17
    59 #define UPA_CONFIG_MID_MASK     0x1f
    60 
    6157int ofw_cpu(void)
    6258{
     
    7571        current_mid >>= UPA_CONFIG_MID_SHIFT;
    7672        current_mid &= UPA_CONFIG_MID_MASK;
     73
     74        int cpus;
    7775       
    78         for (; node != 0 && node != -1; node = ofw_get_peer_node(node)) {
     76        for (cpus = 0; node != 0 && node != -1; node = ofw_get_peer_node(node), cpus++) {
    7977                if (ofw_get_property(node, "device_type", type_name, sizeof(type_name)) > 0) {
    8078                        if (strcmp(type_name, "cpu") == 0) {
     
    9492        }
    9593
    96         return 1;
     94        return cpus;
    9795}
  • boot/arch/sparc64/loader/register.h

    r86b31ba9 ra9ac978  
    3333#define PSTATE_AM_BIT   8
    3434
     35#define ASI_UPA_CONFIG          0x4a
     36#define UPA_CONFIG_MID_SHIFT    17
     37#define UPA_CONFIG_MID_MASK     0x1f
     38
    3539#endif
  • kernel/arch/sparc64/Makefile.inc

    r86b31ba9 ra9ac978  
    7171CONFIG_OFW_TREE = y
    7272
     73ifeq ($(CONFIG_SMP),y)
     74        DEFS += -DCONFIG_SMP
     75endif
     76
    7377ARCH_SOURCES = \
    7478        arch/$(ARCH)/src/cpu/cpu.c \
     
    99103        arch/$(ARCH)/src/drivers/scr.c
    100104
     105ifeq ($(CONFIG_SMP),y)
     106ARCH_SOURCES += \
     107        arch/$(ARCH)/src/smp/ipi.c \
     108        arch/$(ARCH)/src/smp/smp.c
     109endif
     110
    101111ifeq ($(CONFIG_TSB),y)
    102112ARCH_SOURCES += \
  • kernel/arch/sparc64/include/atomic.h

    r86b31ba9 ra9ac978  
    9797{
    9898        uint64_t v = 1;
     99        volatile uintptr_t x = (uint64_t) &val->count;
    99100
    100         __asm__ volatile ("casx %0, %2, %1\n" : "+m" (*val), "+r" (v) : "r" (0));
     101        __asm__ volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *) x)), "+r" (v) : "r" (0));
    101102
    102103        return v;
     
    107108        uint64_t tmp1 = 1;
    108109        uint64_t tmp2;
     110
     111        volatile uintptr_t x = (uint64_t) &val->count;
    109112
    110113        __asm__ volatile (
     
    120123                "nop\n"
    121124        "2:\n"
    122                 : "+m" (*val), "+r" (tmp1), "+r" (tmp2) : "r" (0)
     125                : "+m" (*((uint64_t *) x)), "+r" (tmp1), "+r" (tmp2) : "r" (0)
    123126        );
    124127       
  • kernel/arch/sparc64/include/cpu.h

    r86b31ba9 ra9ac978  
    3636#define KERN_sparc64_CPU_H_
    3737
     38#include <arch/types.h>
    3839#include <arch/register.h>
    3940
     
    5253
    5354struct cpu_arch {
     55        uint32_t mid;                   /**< Processor ID as read from UPA_CONFIG. */
    5456        ver_reg_t ver;
    55         uint32_t clock_frequency;
     57        uint32_t clock_frequency;       /**< Processor frequency in MHz. */
    5658};
    5759       
  • kernel/arch/sparc64/include/interrupt.h

    r86b31ba9 ra9ac978  
    4141#include <arch/regdef.h>
    4242
    43 #define IRQ_COUNT       1       /* TODO */
     43#define IRQ_COUNT       1                       /* TODO */
    4444
    4545#define IVT_ITEMS       15
    4646#define IVT_FIRST       1
     47
     48#define VECTOR_TLB_SHOOTDOWN_IPI        0       /* TODO */
    4749
    4850struct istate {
  • kernel/arch/sparc64/include/regdef.h

    r86b31ba9 ra9ac978  
    5656#define WSTATE_OTHER(n)         ((n)<<3)
    5757
     58#define UPA_CONFIG_MID_SHIFT    17
     59#define UPA_CONFIG_MID_MASK     0x1f
     60
    5861#endif
    5962
  • kernel/arch/sparc64/src/cpu/cpu.c

    r86b31ba9 ra9ac978  
    5151       
    5252        upa_config.value = upa_config_read();
     53        CPU->arch.mid = upa_config.mid;
     54       
    5355        node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu");
    5456        while (node) {
     
    5860                if (prop && prop->value) {
    5961                        mid = *((uint32_t *) prop->value);
    60                         if (mid == upa_config.mid) {
     62                        if (mid == CPU->arch.mid) {
    6163                                prop = ofw_tree_getprop(node, "clock-frequency");
    6264                                if (prop && prop->value)
     
    7981/** Print version information for a processor.
    8082 *
     83 * This function is called by the bootstrap processor.
     84 *
    8185 * @param m Processor structure of the CPU for which version information is to be printed.
    8286 */
     
    8589        char *manuf, *impl;
    8690
    87         switch (CPU->arch.ver.manuf) {
    88             case MANUF_FUJITSU:
     91        switch (m->arch.ver.manuf) {
     92        case MANUF_FUJITSU:
    8993                manuf = "Fujitsu";
    9094                break;
    91             case MANUF_ULTRASPARC:
     95        case MANUF_ULTRASPARC:
    9296                manuf = "UltraSPARC";
    9397                break;
    94             case MANUF_SUN:
     98        case MANUF_SUN:
    9599                manuf = "Sun";
    96100                break;
    97             default:
     101        default:
    98102                manuf = "Unknown";
    99103                break;
     
    101105       
    102106        switch (CPU->arch.ver.impl) {
    103             case IMPL_ULTRASPARCI:
     107        case IMPL_ULTRASPARCI:
    104108                impl = "UltraSPARC I";
    105109                break;
    106             case IMPL_ULTRASPARCII:
     110        case IMPL_ULTRASPARCII:
    107111                impl = "UltraSPARC II";
    108112                break;
    109             case IMPL_ULTRASPARCII_I:
     113        case IMPL_ULTRASPARCII_I:
    110114                impl = "UltraSPARC IIi";
    111115                break;
    112             case IMPL_ULTRASPARCII_E:
     116        case IMPL_ULTRASPARCII_E:
    113117                impl = "UltraSPARC IIe";
    114118                break;
    115             case IMPL_ULTRASPARCIII:
     119        case IMPL_ULTRASPARCIII:
    116120                impl = "UltraSPARC III";
    117121                break;
    118             case IMPL_ULTRASPARCIV_PLUS:
     122        case IMPL_ULTRASPARCIV_PLUS:
    119123                impl = "UltraSPARC IV+";
    120124                break;
    121             case IMPL_SPARC64V:
     125        case IMPL_SPARC64V:
    122126                impl = "SPARC 64V";
    123127                break;
    124             default:
     128        default:
    125129                impl = "Unknown";
    126130                break;
     
    128132
    129133        printf("cpu%d: manuf=%s, impl=%s, mask=%d (%dMHz)\n",
    130                 CPU->id, manuf, impl, CPU->arch.ver.mask, CPU->arch.clock_frequency/1000000);
     134                m->id, manuf, impl, m->arch.ver.mask, m->arch.clock_frequency/1000000);
    131135}
    132136
  • kernel/arch/sparc64/src/mm/as.c

    r86b31ba9 ra9ac978  
    3838#include <genarch/mm/asid_fifo.h>
    3939#include <debug.h>
     40#include <config.h>
    4041
    4142#ifdef CONFIG_TSB
     
    5253void as_arch_init(void)
    5354{
    54         as_operations = &as_ht_operations;
    55         asid_fifo_init();
     55        if (config.cpu_active == 1) {
     56                as_operations = &as_ht_operations;
     57                asid_fifo_init();
     58        }
    5659}
    5760
  • kernel/arch/sparc64/src/mm/frame.c

    r86b31ba9 ra9ac978  
    5454        pfn_t confdata;
    5555
    56         for (i = 0; i < bootinfo.memmap.count; i++) {
    57                 uintptr_t start = bootinfo.memmap.zones[i].start;
    58                 size_t size = bootinfo.memmap.zones[i].size;
     56        if (config.cpu_active == 1) {
     57                for (i = 0; i < bootinfo.memmap.count; i++) {
     58                        uintptr_t start = bootinfo.memmap.zones[i].start;
     59                        size_t size = bootinfo.memmap.zones[i].size;
    5960
    60                 /*
    61                 * The memmap is created by HelenOS boot loader.
    62                 * It already contains no holes.
    63                 */
     61                        /*
     62                        * The memmap is created by HelenOS boot loader.
     63                        * It already contains no holes.
     64                        */
    6465       
    65                 confdata = ADDR2PFN(start);
    66                 if (confdata == 0)
    67                         confdata = 2;
    68                 zone_create(ADDR2PFN(start), SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)), confdata, 0);
     66                        confdata = ADDR2PFN(start);
     67                        if (confdata == 0)
     68                                confdata = 2;
     69                        zone_create(ADDR2PFN(start), SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)), confdata, 0);
    6970               
    70                 last_frame = max(last_frame, start + ALIGN_UP(size, FRAME_SIZE));
     71                        last_frame = max(last_frame, start + ALIGN_UP(size, FRAME_SIZE));
     72                }
    7173        }
    7274
  • kernel/arch/sparc64/src/mm/page.c

    r86b31ba9 ra9ac978  
    4141#include <debug.h>
    4242#include <align.h>
     43#include <config.h>
    4344
     45#ifdef CONFIG_SMP
     46/** Entries locked in DTLB of BSP.
     47 *
     48 * Application processors need to have the same locked entries
     49 * in their DTLBs as the bootstrap processor.
     50 */
     51static struct {
     52        uintptr_t virt_page;
     53        uintptr_t phys_page;
     54        int pagesize_code;
     55} bsp_locked_dtlb_entry[DTLB_ENTRY_COUNT];
     56
     57/** Number of entries in bsp_locked_dtlb_entry array. */
     58static count_t bsp_locked_dtlb_entries = 0;
     59#endif /* CONFIG_SMP */
     60
     61/** Perform sparc64 specific initialization of paging. */
    4462void page_arch_init(void)
    4563{
    46         page_mapping_operations = &ht_mapping_operations;
     64        if (config.cpu_active == 1) {
     65                page_mapping_operations = &ht_mapping_operations;
     66        } else {
     67
     68#ifdef CONFIG_SMP
     69                int i;
     70
     71                /*
     72                 * Copy locked DTLB entries from the BSP.
     73                 */             
     74                for (i = 0; i < bsp_locked_dtlb_entries; i++) {
     75                        dtlb_insert_mapping(bsp_locked_dtlb_entry[i].virt_page,
     76                                bsp_locked_dtlb_entry[i].phys_page, bsp_locked_dtlb_entry[i].pagesize_code,
     77                                true, false);
     78                }
     79#endif 
     80
     81        }
    4782}
    4883
     
    68103        int i;
    69104
     105        ASSERT(config.cpu_active == 1);
     106
    70107        struct {
    71                 int pagesize;
     108                int pagesize_code;
    72109                size_t increment;
    73110                count_t count;
     
    102139        last_frame = ALIGN_UP(virtaddr + size, 1<<(order + FRAME_WIDTH));
    103140       
    104         for (i = 0; i < sizemap[order].count; i++)
     141        for (i = 0; i < sizemap[order].count; i++) {
     142                /*
     143                 * First, insert the mapping into DTLB.
     144                 */
    105145                dtlb_insert_mapping(virtaddr + i*sizemap[order].increment,
    106146                                    physaddr + i*sizemap[order].increment,
    107                                     sizemap[order].pagesize, true, false);
     147                                    sizemap[order].pagesize_code, true, false);
     148       
     149#ifdef CONFIG_SMP       
     150                /*
     151                 * Second, save the information about the mapping for APs.
     152                 */
     153                bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].virt_page = virtaddr + i*sizemap[order].increment;
     154                bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].phys_page = physaddr + i*sizemap[order].increment;
     155                bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].pagesize_code = sizemap[order].pagesize_code;
     156                bsp_locked_dtlb_entries++;
     157#endif
     158        }
    108159       
    109160        return virtaddr;
  • kernel/arch/sparc64/src/sparc64.c

    r86b31ba9 ra9ac978  
    7171void arch_pre_mm_init(void)
    7272{
    73         trap_init();
     73        if (config.cpu_active == 1)
     74                trap_init();
    7475}
    7576
    7677void arch_post_mm_init(void)
    7778{
    78         standalone_sparc64_console_init();
     79        if (config.cpu_active == 1)
     80                standalone_sparc64_console_init();
    7981}
    8082
     
    9193        thread_t *t;
    9294
    93         /*
    94          * Create thread that polls keyboard.
    95          */
    96         t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll");
    97         if (!t)
    98                 panic("cannot create kkbdpoll\n");
    99         thread_ready(t);
     95        if (config.cpu_active == 1) {
     96                /*
     97                 * Create thread that polls keyboard.
     98                 */
     99                t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll");
     100                if (!t)
     101                        panic("cannot create kkbdpoll\n");
     102                thread_ready(t);
     103        }
    100104}
    101105
  • kernel/arch/sparc64/src/start.S

    r86b31ba9 ra9ac978  
    2727#
    2828
     29#include <arch/arch.h>
    2930#include <arch/regdef.h>
    3031#include <arch/boot/boot.h>
     
    3334#include <arch/mm/tlb.h>
    3435#include <arch/mm/tte.h>
     36
     37#ifdef CONFIG_SMP
     38#include <arch/context_offset.h>
     39#endif
    3540
    3641.register %g2, #scratch
     
    227232        wrpr %g0, 0, %tl
    228233
    229         brz %l7, 2f                             ! skip if you are not the bootstrap CPU
     234        brz %l7, 1f                             ! skip if you are not the bootstrap CPU
     235        nop
    230236
    231237        call arch_pre_main
     
    237243        /* Not reached. */
    238244
     2450:
     246        ba 0b
     247        nop
     248
     249
     250        /*
     251         * Read MID from the processor.
     252         */
     2531:
     254        ldxa [%g0] ASI_UPA_CONFIG, %g1
     255        srlx %g1, UPA_CONFIG_MID_SHIFT, %g1
     256        and %g1, UPA_CONFIG_MID_MASK, %g1
     257
     258        /*
     259         * Active loop for APs until the BSP picks them up.
     260         * A processor cannot leave the loop until the
     261         * global variable 'waking_up_mid' equals its
     262         * MID.
     263         */
     264        set waking_up_mid, %g2
    2392652:
    240         b 2b
    241         nop
     266        ldx [%g2], %g3
     267        cmp %g3, %g1
     268        bne 2b
     269        nop
     270
     271#ifdef CONFIG_SMP
     272        /*
     273         * Configure stack for the AP.
     274         * The AP is expected to use the stack saved
     275         * in the ctx global variable.
     276         */
     277        set ctx, %g1
     278        add %g1, OFFSET_SP, %g1
     279        ldx [%g1], %o6
     280
     281        call main_ap
     282        nop
     283#endif
     284
     285        /* Not reached. */
     286       
     2870:
     288        ba 0b
     289        nop
  • kernel/kernel.config

    r86b31ba9 ra9ac978  
    7272
    7373# Support for SMP
    74 ! [ARCH=ia32|ARCH=amd64|ARCH=xen32] CONFIG_SMP (y/n)
     74! [ARCH=ia32|ARCH=amd64|ARCH=xen32|ARCH=sparc64] CONFIG_SMP (y/n)
    7575
    7676# Improved support for hyperthreading
Note: See TracChangeset for help on using the changeset viewer.