The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mips/rmi/xlr_machdep.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2006-2009 RMI Corporation
    3  * Copyright (c) 2002-2004 Juli Mallett <jmallett@FreeBSD.org>
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  */
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD: stable/8/sys/mips/rmi/xlr_machdep.c 215938 2010-11-27 12:26:40Z jchandra $");
   30 
   31 #include "opt_ddb.h"
   32 
   33 #include <sys/param.h>
   34 #include <sys/bus.h>
   35 #include <sys/conf.h>
   36 #include <sys/rtprio.h>
   37 #include <sys/systm.h>
   38 #include <sys/interrupt.h>
   39 #include <sys/limits.h>
   40 #include <sys/lock.h>
   41 #include <sys/malloc.h>
   42 #include <sys/mutex.h>
   43 #include <sys/random.h>
   44 
   45 #include <sys/cons.h>           /* cinit() */
   46 #include <sys/kdb.h>
   47 #include <sys/reboot.h>
   48 #include <sys/queue.h>
   49 #include <sys/smp.h>
   50 #include <sys/timetc.h>
   51 
   52 #include <vm/vm.h>
   53 #include <vm/vm_page.h>
   54 
   55 #include <machine/cpu.h>
   56 #include <machine/cpufunc.h>
   57 #include <machine/cpuinfo.h>
   58 #include <machine/cpuregs.h>
   59 #include <machine/frame.h>
   60 #include <machine/hwfunc.h>
   61 #include <machine/md_var.h>
   62 #include <machine/asm.h>
   63 #include <machine/pmap.h>
   64 #include <machine/trap.h>
   65 #include <machine/clock.h>
   66 #include <machine/fls64.h>
   67 #include <machine/intr_machdep.h>
   68 #include <machine/smp.h>
   69 
   70 #include <mips/rmi/iomap.h>
   71 #include <mips/rmi/msgring.h>
   72 #include <mips/rmi/interrupt.h>
   73 #include <mips/rmi/pic.h>
   74 #include <mips/rmi/board.h>
   75 #include <mips/rmi/rmi_mips_exts.h>
   76 #include <mips/rmi/rmi_boot_info.h>
   77 
   78 void mpwait(void);
   79 unsigned long xlr_io_base = (unsigned long)(DEFAULT_XLR_IO_BASE);
   80 
   81 /* 4KB static data aread to keep a copy of the bootload env until
   82    the dynamic kenv is setup */
   83 char boot1_env[4096];
   84 int rmi_spin_mutex_safe=0;
   85 struct mtx xlr_pic_lock;
   86 
   87 /*
   88  * Parameters from boot loader
   89  */
   90 struct boot1_info xlr_boot1_info;
   91 int xlr_run_mode;
   92 int xlr_argc;
   93 int32_t *xlr_argv, *xlr_envp;
   94 uint64_t cpu_mask_info;
   95 uint32_t xlr_online_cpumask;
   96 uint32_t xlr_core_cpu_mask = 0x1;       /* Core 0 thread 0 is always there */
   97 
   98 int xlr_shtlb_enabled;
   99 int xlr_ncores;
  100 int xlr_threads_per_core;
  101 uint32_t xlr_hw_thread_mask;
  102 int xlr_cpuid_to_hwtid[MAXCPU];
  103 int xlr_hwtid_to_cpuid[MAXCPU];
  104 
  105 static void 
  106 xlr_setup_mmu_split(void)
  107 {
  108         uint64_t mmu_setup;
  109         int val = 0;
  110 
  111         if (xlr_threads_per_core == 4 && xlr_shtlb_enabled == 0)
  112                 return;   /* no change from boot setup */       
  113 
  114         switch (xlr_threads_per_core) {
  115         case 1: 
  116                 val = 0; break;
  117         case 2: 
  118                 val = 2; break;
  119         case 4: 
  120                 val = 3; break;
  121         }
  122         
  123         mmu_setup = read_xlr_ctrl_register(4, 0);
  124         mmu_setup = mmu_setup & ~0x06;
  125         mmu_setup |= (val << 1);
  126 
  127         /* turn on global mode */
  128         if (xlr_shtlb_enabled)
  129                 mmu_setup |= 0x01;
  130 
  131         write_xlr_ctrl_register(4, 0, mmu_setup);
  132 }
  133 
  134 static void
  135 xlr_parse_mmu_options(void)
  136 {
  137 #ifdef notyet
  138         char *hw_env, *start, *end;
  139 #endif
  140         uint32_t cpu_map;
  141         uint8_t core0_thr_mask, core_thr_mask;
  142         int i, j, k;
  143 
  144         /* First check for the shared TLB setup */
  145         xlr_shtlb_enabled = 0;
  146 #ifdef notyet
  147         /* 
  148          * We don't support sharing TLB per core - TODO
  149          */
  150         xlr_shtlb_enabled = 0;
  151         if ((hw_env = getenv("xlr.shtlb")) != NULL) {
  152                 start = hw_env;
  153                 tmp = strtoul(start, &end, 0);
  154                 if (start != end)
  155                         xlr_shtlb_enabled = (tmp != 0);
  156                 else
  157                         printf("Bad value for xlr.shtlb [%s]\n", hw_env);
  158                 freeenv(hw_env);
  159         }
  160 #endif
  161         /*
  162          * XLR supports splitting the 64 TLB entries across one, two or four
  163          * threads (split mode).  XLR also allows the 64 TLB entries to be shared
  164          * across all threads in the core using a global flag (shared TLB mode).
  165          * We will support 1/2/4 threads in split mode or shared mode.
  166          *
  167          */
  168         xlr_ncores = 1;
  169         cpu_map = xlr_boot1_info.cpu_online_map;
  170 
  171 #ifndef SMP /* Uniprocessor! */
  172         if (cpu_map != 0x1) {
  173                 printf("WARNING: Starting uniprocessor kernel on cpumask [0x%lx]!\n"
  174                    "WARNING: Other CPUs will be unused.\n", (u_long)cpu_map);
  175                 cpu_map = 0x1;
  176         }
  177 #endif
  178         core0_thr_mask = cpu_map & 0xf;
  179         switch (core0_thr_mask) {
  180         case 1:
  181                 xlr_threads_per_core = 1; break;
  182         case 3:
  183                 xlr_threads_per_core = 2; break;
  184         case 0xf: 
  185                 xlr_threads_per_core = 4; break;
  186         default:
  187                 goto unsupp;
  188         }
  189 
  190         /* Verify other cores CPU masks */
  191         for (i = 1; i < XLR_MAX_CORES; i++) {
  192                 core_thr_mask = (cpu_map >> (i*4)) & 0xf;
  193                 if (core_thr_mask) {
  194                         if (core_thr_mask != core0_thr_mask)
  195                                 goto unsupp; 
  196                         xlr_ncores++;
  197                 }
  198         }
  199         xlr_hw_thread_mask = cpu_map;
  200 
  201         /* setup hardware processor id to cpu id mapping */
  202         for (i = 0; i< MAXCPU; i++)
  203                 xlr_cpuid_to_hwtid[i] = 
  204                     xlr_hwtid_to_cpuid [i] = -1;
  205         for (i = 0, k = 0; i < XLR_MAX_CORES; i++) {
  206                 if (((cpu_map >> (i*4)) & 0xf) == 0)
  207                         continue;
  208                 for (j = 0; j < xlr_threads_per_core; j++) {
  209                         xlr_cpuid_to_hwtid[k] = i*4 + j;
  210                         xlr_hwtid_to_cpuid[i*4 + j] = k;
  211                         k++;
  212                 }
  213         }
  214 
  215         /* setup for the startup core */
  216         xlr_setup_mmu_split();
  217         return;
  218 
  219 unsupp:
  220         printf("ERROR : Unsupported CPU mask [use 1,2 or 4 threads per core].\n"
  221             "\tcore0 thread mask [%lx], boot cpu mask [%lx]\n"
  222             "\tUsing default, 16 TLB entries per CPU, split mode\n", 
  223             (u_long)core0_thr_mask, (u_long)cpu_map);
  224         panic("Invalid CPU mask - halting.\n");
  225         return;
  226 }
  227 
  228 static void 
  229 xlr_set_boot_flags(void)
  230 {
  231         char *p;
  232 
  233         p = getenv("bootflags");
  234         if (p == NULL)
  235                 p = getenv("boot_flags");  /* old style */
  236         if (p == NULL)
  237                 return;
  238 
  239         for (; p && *p != '\0'; p++) {
  240                 switch (*p) {
  241                 case 'd':
  242                 case 'D':
  243                         boothowto |= RB_KDB;
  244                         break;
  245                 case 'g':
  246                 case 'G':
  247                         boothowto |= RB_GDB;
  248                         break;
  249                 case 'v':
  250                 case 'V':
  251                         boothowto |= RB_VERBOSE;
  252                         break;
  253 
  254                 case 's':       /* single-user (default, supported for sanity) */
  255                 case 'S':
  256                         boothowto |= RB_SINGLE;
  257                         break;
  258 
  259                 default:
  260                         printf("Unrecognized boot flag '%c'.\n", *p);
  261                         break;
  262                 }
  263         }
  264 
  265         freeenv(p);
  266         return;
  267 }
  268 extern uint32_t _end;
  269 
  270 static void
  271 mips_init(void)
  272 {
  273         init_param1();
  274         init_param2(physmem);
  275 
  276         mips_cpu_init();
  277         cpuinfo.cache_coherent_dma = TRUE;
  278         pmap_bootstrap();
  279 #ifdef DDB
  280         kdb_init();
  281         if (boothowto & RB_KDB) {
  282                 kdb_enter("Boot flags requested debugger", NULL);
  283         }
  284 #endif
  285         mips_proc0_init();
  286         mutex_init();
  287 }
  288 
  289 u_int
  290 platform_get_timecount(struct timecounter *tc __unused)
  291 {
  292 
  293         return (0xffffffffU - pic_timer_count32(PIC_CLOCK_TIMER));
  294 }
  295 
  296 static void 
  297 xlr_pic_init(void)
  298 {
  299         struct timecounter pic_timecounter = {
  300                 platform_get_timecount, /* get_timecount */
  301                 0,                      /* no poll_pps */
  302                 ~0U,                    /* counter_mask */
  303                 PIC_TIMER_HZ,           /* frequency */
  304                 "XLRPIC",               /* name */
  305                 2000,                   /* quality (adjusted in code) */
  306         };
  307         xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET);
  308         int i, irq;
  309 
  310         write_c0_eimr64(0ULL);
  311         mtx_init(&xlr_pic_lock, "pic", NULL, MTX_SPIN);
  312         xlr_write_reg(mmio, PIC_CTRL, 0);
  313 
  314         /* Initialize all IRT entries */
  315         for (i = 0; i < PIC_NUM_IRTS; i++) {
  316                 irq = PIC_INTR_TO_IRQ(i);
  317 
  318                 /*
  319                  * Disable all IRTs. Set defaults (local scheduling, high
  320                  * polarity, level * triggered, and CPU irq)
  321                  */
  322                 xlr_write_reg(mmio, PIC_IRT_1(i), (1 << 30) | (1 << 6) | irq);
  323                 /* Bind all PIC irqs to cpu 0 */
  324                 xlr_write_reg(mmio, PIC_IRT_0(i), 0x01);
  325         }
  326 
  327         /* Setup timer 7 of PIC as a timestamp, no interrupts */
  328         pic_init_timer(PIC_CLOCK_TIMER);
  329         pic_set_timer(PIC_CLOCK_TIMER, ~UINT64_C(0));
  330         platform_timecounter = &pic_timecounter;
  331 }
  332 
  333 static void
  334 xlr_mem_init(void)
  335 {
  336         struct xlr_boot1_mem_map *boot_map;
  337         vm_size_t physsz = 0;
  338         int i, j;
  339 
  340         /* get physical memory info from boot loader */
  341         boot_map = (struct xlr_boot1_mem_map *)
  342             (unsigned long)xlr_boot1_info.psb_mem_map;
  343         for (i = 0, j = 0; i < boot_map->num_entries; i++, j += 2) {
  344                 if (boot_map->physmem_map[i].type == BOOT1_MEM_RAM) {
  345                         if (j == 14) {
  346                                 printf("*** ERROR *** memory map too large ***\n");
  347                                 break;
  348                         }
  349                         if (j == 0) {
  350                                 /* TODO FIXME  */
  351                                 /* start after kernel end */
  352                                 phys_avail[0] = (vm_paddr_t)
  353                                     MIPS_KSEG0_TO_PHYS(&_end) + 0x20000;
  354                                 /* boot loader start */
  355                                 /* HACK to Use bootloaders memory region */
  356                                 /* TODO FIXME  */
  357                                 if (boot_map->physmem_map[0].size == 0x0c000000) {
  358                                         boot_map->physmem_map[0].size = 0x0ff00000;
  359                                 }
  360                                 phys_avail[1] = boot_map->physmem_map[0].addr +
  361                                     boot_map->physmem_map[0].size;
  362                                 printf("First segment: addr:%p -> %p \n",
  363                                        (void *)phys_avail[0], 
  364                                        (void *)phys_avail[1]);
  365 
  366                         } else {
  367 /*
  368  * Can't use this code yet, because most of the fixed allocations happen from
  369  * the biggest physical area. If we have more than 512M memory the kernel will try
  370  * to map from the second are which is not in KSEG0 and not mapped
  371  */
  372                                 phys_avail[j] = (vm_paddr_t)
  373                                     boot_map->physmem_map[i].addr;
  374                                 phys_avail[j + 1] = phys_avail[j] +
  375                                     boot_map->physmem_map[i].size;
  376                                 if (phys_avail[j + 1] < phys_avail[j] ) {
  377                                         /* Houston we have an issue. Memory is
  378                                          * larger than possible. Its probably in
  379                                          * 64 bit > 4Gig and we are in 32 bit mode.
  380                                          */
  381                                         phys_avail[j + 1] = 0xfffff000;
  382                                         printf("boot map size was %jx\n",
  383                                             (intmax_t)boot_map->physmem_map[i].size);
  384                                         boot_map->physmem_map[i].size = phys_avail[j + 1]
  385                                             - phys_avail[j];
  386                                         printf("reduced to %jx\n", 
  387                                             (intmax_t)boot_map->physmem_map[i].size);
  388                                 }
  389                                 printf("Next segment : addr:%p -> %p \n",
  390                                        (void *)phys_avail[j], 
  391                                        (void *)phys_avail[j+1]);
  392                         }
  393                         physsz += boot_map->physmem_map[i].size;
  394                 }
  395         }
  396 
  397         /* FIXME XLR TODO */
  398         phys_avail[j] = phys_avail[j + 1] = 0;
  399         realmem = physmem = btoc(physsz);
  400 }
  401 
  402 void
  403 platform_start(__register_t a0 __unused,
  404     __register_t a1 __unused,
  405     __register_t a2 __unused,
  406     __register_t a3 __unused)
  407 {
  408         int i, j;
  409 #ifdef SMP
  410         uint32_t tmp;
  411         void (*wakeup) (void *, void *, unsigned int);
  412 #endif
  413 
  414         /* XXX FIXME the code below is not 64 bit clean */
  415         /* Save boot loader and other stuff from scratch regs */
  416         xlr_boot1_info = *(struct boot1_info *)(intptr_t)(int)read_c0_register32(MIPS_COP_0_OSSCRATCH, 0);
  417         cpu_mask_info = read_c0_register64(MIPS_COP_0_OSSCRATCH, 1);
  418         xlr_online_cpumask = read_c0_register32(MIPS_COP_0_OSSCRATCH, 2);
  419         xlr_run_mode = read_c0_register32(MIPS_COP_0_OSSCRATCH, 3);
  420         xlr_argc = read_c0_register32(MIPS_COP_0_OSSCRATCH, 4);
  421         /*
  422          * argv and envp are passed in array of 32bit pointers
  423          */
  424         xlr_argv = (int32_t *)(intptr_t)(int)read_c0_register32(MIPS_COP_0_OSSCRATCH, 5);
  425         xlr_envp = (int32_t *)(intptr_t)(int)read_c0_register32(MIPS_COP_0_OSSCRATCH, 6);
  426 
  427         /* TODO: Verify the magic number here */
  428         /* FIXMELATER: xlr_boot1_info.magic_number */
  429 
  430         /* Initialize pcpu stuff */
  431         mips_pcpu0_init();
  432 
  433         /* initialize console so that we have printf */
  434         boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */
  435 
  436         /* clockrate used by delay, so initialize it here */
  437         cpu_clock = xlr_boot1_info.cpu_frequency / 1000000;
  438 
  439         /*
  440          * Note the time counter on CPU0 runs not at system clock speed, but
  441          * at PIC time counter speed (which is returned by
  442          * platform_get_frequency(). Thus we do not use
  443          * xlr_boot1_info.cpu_frequency here.
  444          */
  445         mips_timer_early_init(xlr_boot1_info.cpu_frequency);
  446 
  447         /* Init console please */
  448         cninit();
  449         printf("Environment (from %d args):\n", xlr_argc - 1);
  450         if (xlr_argc == 1)
  451                 printf("\tNone\n");
  452         for (i = 1, j = 0; i < xlr_argc; i++) {
  453                 char *arg;
  454                 int len;
  455 
  456                 arg = (char *)(intptr_t)xlr_argv[i];
  457                 len = strlen(arg) + 1;    /* include '\0' */
  458                 if (j + len + 1 > sizeof(boot1_env)) {
  459                         printf("*** Environment could not be copied in full\n");
  460                         break;
  461                 }
  462                 printf("\t%s\n", arg);
  463                 memcpy(&boot1_env[j], arg, len); 
  464                 j += len;
  465         }
  466         boot1_env[j] = '\0';
  467         kern_envp = boot1_env;
  468 
  469         xlr_set_boot_flags();
  470         xlr_parse_mmu_options();
  471 
  472         xlr_mem_init();
  473         /* Set up hz, among others. */
  474         mips_init();
  475 
  476 #ifdef SMP
  477         /*
  478          * If thread 0 of any core is not available then mark whole core as
  479          * not available
  480          */
  481         tmp = xlr_boot1_info.cpu_online_map;
  482         for (i = 4; i < MAXCPU; i += 4) {
  483                 if ((tmp & (0xf << i)) && !(tmp & (0x1 << i))) {
  484                         /*
  485                          * Oops.. thread 0 is not available. Disable whole
  486                          * core
  487                          */
  488                         tmp = tmp & ~(0xf << i);
  489                         printf("WARNING: Core %d is disabled because thread 0"
  490                             " of this core is not enabled.\n", i / 4);
  491                 }
  492         }
  493         xlr_boot1_info.cpu_online_map = tmp;
  494 
  495         /* Wakeup Other cpus, and put them in bsd park code. */
  496         wakeup = ((void (*) (void *, void *, unsigned int))
  497             (unsigned long)(xlr_boot1_info.wakeup));
  498         printf("Waking up CPUs 0x%jx.\n", 
  499             (intmax_t)xlr_boot1_info.cpu_online_map & ~(0x1U));
  500         if (xlr_boot1_info.cpu_online_map & ~(0x1U))
  501                 wakeup(mpwait, 0,
  502                     (unsigned int)xlr_boot1_info.cpu_online_map);
  503 #endif
  504 
  505         /* xlr specific post initialization */
  506         /* initialize other on chip stuff */
  507         xlr_board_info_setup();
  508         xlr_msgring_config();
  509         xlr_pic_init();
  510         xlr_msgring_cpu_init();
  511 
  512         mips_timer_init_params(xlr_boot1_info.cpu_frequency, 0);
  513 
  514         printf("Platform specific startup now completes\n");
  515 }
  516 
  517 void 
  518 platform_cpu_init()
  519 {
  520 }
  521 
  522 void
  523 platform_identify(void)
  524 {
  525 
  526         printf("Board [%d:%d], processor 0x%08x\n", (int)xlr_boot1_info.board_major_version,
  527             (int)xlr_boot1_info.board_minor_version, mips_rd_prid());
  528 }
  529 
  530 /*
  531  * XXX Maybe return the state of the watchdog in enter, and pass it to
  532  * exit?  Like spl().
  533  */
  534 void
  535 platform_trap_enter(void)
  536 {
  537 }
  538 
  539 void
  540 platform_reset(void)
  541 {
  542         xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_GPIO_OFFSET);
  543 
  544         /* write 1 to GPIO software reset register */
  545         xlr_write_reg(mmio, 8, 1);
  546 }
  547 
  548 void
  549 platform_trap_exit(void)
  550 {
  551 }
  552 
  553 #ifdef SMP
  554 int xlr_ap_release[MAXCPU];
  555 
  556 int
  557 platform_start_ap(int cpuid)
  558 {
  559         int hwid = xlr_cpuid_to_hwtid[cpuid];
  560 
  561         if (xlr_boot1_info.cpu_online_map & (1<<hwid)) {
  562                 /*
  563                  * other cpus are enabled by the boot loader and they will be 
  564                  * already looping in mpwait, release them
  565                  */
  566                 atomic_store_rel_int(&xlr_ap_release[hwid], 1);
  567                 return (0);
  568         } else
  569                 return (-1);
  570 }
  571 
  572 void
  573 platform_init_ap(int cpuid)
  574 {
  575         uint32_t stat;
  576 
  577         /* The first thread has to setup the core MMU split  */
  578         if (xlr_thr_id() == 0)
  579                 xlr_setup_mmu_split();
  580 
  581         /* Setup interrupts for secondary CPUs here */
  582         stat = mips_rd_status();
  583         KASSERT((stat & MIPS_SR_INT_IE) == 0,
  584             ("Interrupts enabled in %s!", __func__));
  585         stat |= MIPS_SR_COP_2_BIT | MIPS_SR_COP_0_BIT;
  586         mips_wr_status(stat);
  587 
  588         write_c0_eimr64(0ULL);
  589         xlr_enable_irq(IRQ_IPI);
  590         xlr_enable_irq(IRQ_TIMER);
  591         if (xlr_thr_id() == 0) {
  592                 xlr_msgring_cpu_init(); 
  593                 xlr_enable_irq(IRQ_MSGRING);
  594         }
  595 
  596         return;
  597 }
  598 
  599 int
  600 platform_ipi_intrnum(void) 
  601 {
  602 
  603         return (IRQ_IPI);
  604 }
  605 
  606 void
  607 platform_ipi_send(int cpuid)
  608 {
  609 
  610         pic_send_ipi(xlr_cpuid_to_hwtid[cpuid], platform_ipi_intrnum());
  611 }
  612 
  613 void
  614 platform_ipi_clear(void)
  615 {
  616 }
  617 
  618 int
  619 platform_processor_id(void)
  620 {
  621 
  622         return (xlr_hwtid_to_cpuid[xlr_cpu_id()]);
  623 }
  624 
  625 int
  626 platform_num_processors(void)
  627 {
  628 
  629         return (xlr_ncores * xlr_threads_per_core);
  630 }
  631 
  632 struct cpu_group *
  633 platform_smp_topo()
  634 {
  635 
  636         return (smp_topo_2level(CG_SHARE_L2, xlr_ncores, CG_SHARE_L1,
  637                 xlr_threads_per_core, CG_FLAG_THREAD));
  638 }
  639 #endif

Cache object: 57554d40f294094814cfe12e2ddd1876


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.