1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #include <sys/cpuvar.h>
  28 #include <sys/param.h>
  29 #include <sys/systm.h>
  30 #include <sys/sunddi.h>
  31 #include <sys/ddi.h>
  32 #include <sys/esunddi.h>
  33 #include <sys/sysmacros.h>
  34 #include <sys/note.h>
  35 
  36 #include <sys/modctl.h>           /* for modload() */
  37 #include <sys/platform_module.h>
  38 #include <sys/errno.h>
  39 #include <sys/daktari.h>
  40 #include <sys/machsystm.h>
  41 #include <sys/promif.h>
  42 #include <vm/page.h>
  43 #include <sys/memnode.h>
  44 #include <vm/vm_dep.h>
  45 
  46 /* I2C Stuff */
  47 #include <sys/i2c/clients/i2c_client.h>
  48 
  49 
  50 int (*p2get_mem_unum)(int, uint64_t, char *, int, int *);
  51 
  52 /* Daktari Keyswitch Information */
  53 #define DAK_KEY_POLL_PORT       3
  54 #define DAK_KEY_POLL_BIT        2
  55 #define DAK_KEY_POLL_INTVL      10
  56 
  57 static  boolean_t       key_locked_bit;
  58 static  clock_t         keypoll_timeout_hz;
  59 
  60 /*
  61  * Table that maps memory slices to a specific memnode.
  62  */
  63 int slice_to_memnode[DAK_MAX_SLICE];
  64 
  65 /*
  66  * For software memory interleaving support.
  67  */
  68 static  void update_mem_bounds(int, int, int, uint64_t, uint64_t);
  69 
  70 static uint64_t
  71 slice_table[DAK_SBD_SLOTS][DAK_CPUS_PER_BOARD][DAK_BANKS_PER_MC][2];
  72 
  73 #define SLICE_PA        0
  74 #define SLICE_SPAN      1
  75 
  76 int (*daktari_ssc050_get_port_bit) (dev_info_t *, int, int, uint8_t *, int);
  77 extern  void (*abort_seq_handler)();
  78 static  int daktari_dev_search(dev_info_t *, void *);
  79 static  void keyswitch_poll(void *);
  80 static  void daktari_abort_seq_handler(char *msg);
  81 
  82 void
  83 startup_platform(void)
  84 {
  85         /*
  86          * Disable an active h/w watchdog timer
  87          * upon exit to OBP.
  88          */
  89         extern int disable_watchdog_on_exit;
  90         disable_watchdog_on_exit = 1;
  91 }
  92 
  93 int
  94 set_platform_tsb_spares()
  95 {
  96         return (0);
  97 }
  98 
  99 #pragma weak mmu_init_large_pages
 100 
 101 void
 102 set_platform_defaults(void)
 103 {
 104         extern void mmu_init_large_pages(size_t);
 105 
 106         if ((mmu_page_sizes == max_mmu_page_sizes) &&
 107             (mmu_ism_pagesize != DEFAULT_ISM_PAGESIZE)) {
 108                 if (&mmu_init_large_pages)
 109                         mmu_init_large_pages(mmu_ism_pagesize);
 110         }
 111 }
 112 
 113 void
 114 load_platform_modules(void)
 115 {
 116         if (modload("misc", "pcihp") < 0) {
 117                 cmn_err(CE_NOTE, "pcihp driver failed to load");
 118         }
 119         if (modload("drv", "pmc") < 0) {
 120                 cmn_err(CE_NOTE, "pmc driver failed to load");
 121         }
 122 
 123 }
 124 
 125 void
 126 load_platform_drivers(void)
 127 {
 128         char **drv;
 129         dev_info_t      *keysw_dip;
 130 
 131         static char *boot_time_drivers[] = {
 132                 "hpc3130",
 133                 "todds1287",
 134                 "mc-us3",
 135                 "ssc050",
 136                 "pcisch",
 137                 NULL
 138         };
 139 
 140         for (drv = boot_time_drivers; *drv; drv++) {
 141                 if (i_ddi_attach_hw_nodes(*drv) != DDI_SUCCESS)
 142                         cmn_err(CE_WARN, "Failed to install \"%s\" driver.",
 143                             *drv);
 144         }
 145 
 146         /*
 147          * mc-us3 & ssc050 must stay loaded for plat_get_mem_unum()
 148          * and keyswitch_poll()
 149          */
 150         (void) ddi_hold_driver(ddi_name_to_major("mc-us3"));
 151         (void) ddi_hold_driver(ddi_name_to_major("ssc050"));
 152 
 153         /* Gain access into the ssc050_get_port function */
 154         daktari_ssc050_get_port_bit = (int (*) (dev_info_t *, int, int,
 155             uint8_t *, int)) modgetsymvalue("ssc050_get_port_bit", 0);
 156         if (daktari_ssc050_get_port_bit == NULL) {
 157                 cmn_err(CE_WARN, "cannot find ssc050_get_port_bit");
 158                 return;
 159         }
 160 
 161         ddi_walk_devs(ddi_root_node(), daktari_dev_search, (void *)&keysw_dip);
 162         ASSERT(keysw_dip != NULL);
 163 
 164         /*
 165          * prevent detach of i2c-ssc050
 166          */
 167         e_ddi_hold_devi(keysw_dip);
 168 
 169         keypoll_timeout_hz = drv_usectohz(10 * MICROSEC);
 170         keyswitch_poll(keysw_dip);
 171         abort_seq_handler = daktari_abort_seq_handler;
 172 }
 173 
 174 static int
 175 daktari_dev_search(dev_info_t *dip, void *arg)
 176 {
 177         char            *compatible = NULL; /* Search tree for "i2c-ssc050" */
 178         int             *dev_regs; /* Info about where the device is. */
 179         uint_t          len;
 180         int             err;
 181 
 182         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
 183             "compatible", &compatible) != DDI_PROP_SUCCESS)
 184                 return (DDI_WALK_CONTINUE);
 185 
 186         if (strcmp(compatible, "i2c-ssc050") == 0) {
 187                 ddi_prop_free(compatible);
 188 
 189                 err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
 190                     DDI_PROP_DONTPASS, "reg", &dev_regs, &len);
 191                 if (err != DDI_PROP_SUCCESS) {
 192                         return (DDI_WALK_CONTINUE);
 193                 }
 194                 /*
 195                  * regs[0] contains the bus number and regs[1]
 196                  * contains the device address of the i2c device.
 197                  * 0x82 is the device address of the i2c device
 198                  * from which  the key switch position is read.
 199                  */
 200                 if (dev_regs[0] == 0 && dev_regs[1] == 0x82) {
 201                         *((dev_info_t **)arg) = dip;
 202                         ddi_prop_free(dev_regs);
 203                         return (DDI_WALK_TERMINATE);
 204                 }
 205                 ddi_prop_free(dev_regs);
 206         } else {
 207                 ddi_prop_free(compatible);
 208         }
 209         return (DDI_WALK_CONTINUE);
 210 }
 211 
 212 static void
 213 keyswitch_poll(void *arg)
 214 {
 215         dev_info_t      *dip = arg;
 216         uchar_t port_byte;
 217         int     port = DAK_KEY_POLL_PORT;
 218         int     bit = DAK_KEY_POLL_BIT;
 219         int     err;
 220 
 221         err = daktari_ssc050_get_port_bit(dip, port, bit,
 222             &port_byte, I2C_NOSLEEP);
 223         if (err != 0) {
 224                 cmn_err(CE_WARN, "keyswitch polling disabled: "
 225                     "errno=%d while reading ssc050", err);
 226                 return;
 227         }
 228 
 229         key_locked_bit = (boolean_t)((port_byte & 0x1));
 230         (void) timeout(keyswitch_poll, (caddr_t)dip, keypoll_timeout_hz);
 231 }
 232 
 233 static void
 234 daktari_abort_seq_handler(char *msg)
 235 {
 236         if (key_locked_bit == 0)
 237                 cmn_err(CE_CONT, "KEY in LOCKED position, "
 238                     "ignoring debug enter sequence");
 239         else  {
 240                 debug_enter(msg);
 241         }
 242 }
 243 
 244 
 245 int
 246 plat_cpu_poweron(struct cpu *cp)
 247 {
 248         _NOTE(ARGUNUSED(cp))
 249         return (ENOTSUP);
 250 }
 251 
 252 int
 253 plat_cpu_poweroff(struct cpu *cp)
 254 {
 255         _NOTE(ARGUNUSED(cp))
 256         return (ENOTSUP);
 257 }
 258 
 259 /*
 260  * Given a pfn, return the board and beginning/end of the page's
 261  * memory controller's address range.
 262  */
 263 static int
 264 plat_discover_slice(pfn_t pfn, pfn_t *first, pfn_t *last)
 265 {
 266         int bd, cpu, bank;
 267 
 268         for (bd = 0; bd < DAK_SBD_SLOTS; bd++) {
 269                 for (cpu = 0; cpu < DAK_CPUS_PER_BOARD; cpu++) {
 270                         for (bank = 0; bank < DAK_BANKS_PER_MC; bank++) {
 271                                 uint64_t *slice = slice_table[bd][cpu][bank];
 272                                 uint64_t base = btop(slice[SLICE_PA]);
 273                                 uint64_t len = btop(slice[SLICE_SPAN]);
 274                                 if (len && pfn >= base && pfn < (base + len)) {
 275                                         *first = base;
 276                                         *last = base + len - 1;
 277                                         return (bd);
 278                                 }
 279                         }
 280                 }
 281         }
 282         panic("plat_discover_slice: no slice for pfn 0x%lx\n", pfn);
 283         /* NOTREACHED */
 284 }
 285 
 286 /*ARGSUSED*/
 287 void
 288 plat_freelist_process(int mnode)
 289 {}
 290 
 291 
 292 /*
 293  * Called for each board/cpu/PA range detected in plat_fill_mc().
 294  */
 295 static void
 296 update_mem_bounds(int boardid, int cpuid, int bankid,
 297         uint64_t base, uint64_t size)
 298 {
 299         uint64_t        end;
 300         int             mnode;
 301 
 302         slice_table[boardid][cpuid][bankid][SLICE_PA] = base;
 303         slice_table[boardid][cpuid][bankid][SLICE_SPAN] = size;
 304 
 305         end = base + size - 1;
 306 
 307         /*
 308          * First see if this board already has a memnode associated
 309          * with it.  If not, see if this slice has a memnode.  This
 310          * covers the cases where a single slice covers multiple
 311          * boards (cross-board interleaving) and where a single
 312          * board has multiple slices (1+GB DIMMs).
 313          */
 314         if ((mnode = plat_lgrphand_to_mem_node(boardid)) == -1) {
 315                 if ((mnode = slice_to_memnode[PA_2_SLICE(base)]) == -1)
 316                         mnode = mem_node_alloc();
 317 
 318                 ASSERT(mnode >= 0);
 319                 ASSERT(mnode < MAX_MEM_NODES);
 320                 plat_assign_lgrphand_to_mem_node(boardid, mnode);
 321         }
 322 
 323         base = P2ALIGN(base, (1ul << PA_SLICE_SHIFT));
 324 
 325         while (base < end) {
 326                 slice_to_memnode[PA_2_SLICE(base)] = mnode;
 327                 base += (1ul << PA_SLICE_SHIFT);
 328         }
 329 }
 330 
 331 /*
 332  * Dynamically detect memory slices in the system by decoding
 333  * the cpu memory decoder registers at boot time.
 334  */
 335 void
 336 plat_fill_mc(pnode_t nodeid)
 337 {
 338         uint64_t        mc_addr, saf_addr;
 339         uint64_t        mc_decode[DAK_BANKS_PER_MC];
 340         uint64_t        base, size;
 341         uint64_t        saf_mask;
 342         uint64_t        offset;
 343         uint32_t        regs[4];
 344         int             len;
 345         int             local_mc;
 346         int             portid;
 347         int             boardid;
 348         int             cpuid;
 349         int             i;
 350 
 351         if ((prom_getprop(nodeid, "portid", (caddr_t)&portid) < 0) ||
 352             (portid == -1))
 353                 return;
 354 
 355         /*
 356          * Decode the board number from the MC portid.  Assumes
 357          * portid == safari agentid.
 358          */
 359         boardid = DAK_GETSLOT(portid);
 360         cpuid = DAK_GETSID(portid);
 361 
 362         /*
 363          * The "reg" property returns 4 32-bit values. The first two are
 364          * combined to form a 64-bit address.  The second two are for a
 365          * 64-bit size, but we don't actually need to look at that value.
 366          */
 367         len = prom_getproplen(nodeid, "reg");
 368         if (len != (sizeof (uint32_t) * 4)) {
 369                 prom_printf("Warning: malformed 'reg' property\n");
 370                 return;
 371         }
 372         if (prom_getprop(nodeid, "reg", (caddr_t)regs) < 0)
 373                 return;
 374         mc_addr = ((uint64_t)regs[0]) << 32;
 375         mc_addr |= (uint64_t)regs[1];
 376 
 377         /*
 378          * Figure out whether the memory controller we are examining
 379          * belongs to this CPU or a different one.
 380          */
 381         saf_addr = lddsafaddr(8);
 382         saf_mask = (uint64_t)SAF_MASK;
 383         if ((mc_addr & saf_mask) == saf_addr)
 384                 local_mc = 1;
 385         else
 386                 local_mc = 0;
 387 
 388         for (i = 0; i < DAK_BANKS_PER_MC; i++) {
 389                 /*
 390                  * Memory decode masks are at offsets 0x10 - 0x28.
 391                  */
 392                 offset = 0x10 + (i << 3);
 393 
 394                 /*
 395                  * If the memory controller is local to this CPU, we use
 396                  * the special ASI to read the decode registers.
 397                  * Otherwise, we load the values from a magic address in
 398                  * I/O space.
 399                  */
 400                 if (local_mc)
 401                         mc_decode[i] = lddmcdecode(offset);
 402                 else
 403                         mc_decode[i] = lddphysio(mc_addr | offset);
 404 
 405                 /*
 406                  * If the upper bit is set, we have a valid mask
 407                  */
 408                 if ((int64_t)mc_decode[i] < 0) {
 409                         /*
 410                          * The memory decode register is a bitmask field,
 411                          * so we can decode that into both a base and
 412                          * a span.
 413                          */
 414                         base = MC_BASE(mc_decode[i]) << PHYS2UM_SHIFT;
 415                         size = MC_UK2SPAN(mc_decode[i]);
 416                         update_mem_bounds(boardid, cpuid, i, base, size);
 417                 }
 418         }
 419 }
 420 
 421 
 422 /*
 423  * This routine is run midway through the boot process.  By the time we get
 424  * here, we know about all the active CPU boards in the system, and we have
 425  * extracted information about each board's memory from the memory
 426  * controllers.  We have also figured out which ranges of memory will be
 427  * assigned to which memnodes, so we walk the slice table to build the table
 428  * of memnodes.
 429  */
 430 /* ARGSUSED */
 431 void
 432 plat_build_mem_nodes(prom_memlist_t *list, size_t  nelems)
 433 {
 434         int     slice;
 435         pfn_t   basepfn;
 436         pgcnt_t npgs;
 437 
 438         mem_node_pfn_shift = PFN_SLICE_SHIFT;
 439         mem_node_physalign = (1ull << PA_SLICE_SHIFT);
 440         npgs = 1ull << PFN_SLICE_SHIFT;
 441 
 442         for (slice = 0; slice < DAK_MAX_SLICE; slice++) {
 443                 if (slice_to_memnode[slice] == -1)
 444                         continue;
 445                 basepfn = (uint64_t)slice << PFN_SLICE_SHIFT;
 446                 mem_node_add_slice(basepfn, basepfn + npgs - 1);
 447         }
 448 }
 449 
 450 
 451 
 452 /*
 453  * Daktari support for lgroups.
 454  *
 455  * On Daktari, an lgroup platform handle == slot number.
 456  *
 457  * Mappings between lgroup handles and memnodes are managed
 458  * in addition to mappings between memory slices and memnodes
 459  * to support cross-board interleaving as well as multiple
 460  * slices per board (e.g. >1GB DIMMs). The initial mapping
 461  * of memnodes to lgroup handles is determined at boot time.
 462  */
 463 int
 464 plat_pfn_to_mem_node(pfn_t pfn)
 465 {
 466         return (slice_to_memnode[PFN_2_SLICE(pfn)]);
 467 }
 468 
 469 /*
 470  * Return the platform handle for the lgroup containing the given CPU
 471  *
 472  * For Daktari, lgroup platform handle == slot number
 473  */
 474 lgrp_handle_t
 475 plat_lgrp_cpu_to_hand(processorid_t id)
 476 {
 477         return (DAK_GETSLOT(id));
 478 }
 479 
 480 /*
 481  * Platform specific lgroup initialization
 482  */
 483 void
 484 plat_lgrp_init(void)
 485 {
 486         int i;
 487 
 488         /*
 489          * Initialize lookup tables to invalid values so we catch
 490          * any illegal use of them.
 491          */
 492         for (i = 0; i < DAK_MAX_SLICE; i++) {
 493                 slice_to_memnode[i] = -1;
 494         }
 495 }
 496 
 497 /*
 498  * Return latency between "from" and "to" lgroups
 499  *
 500  * This latency number can only be used for relative comparison
 501  * between lgroups on the running system, cannot be used across platforms,
 502  * and may not reflect the actual latency.  It is platform and implementation
 503  * specific, so platform gets to decide its value.  It would be nice if the
 504  * number was at least proportional to make comparisons more meaningful though.
 505  * NOTE: The numbers below are supposed to be load latencies for uncached
 506  * memory divided by 10.
 507  */
 508 int
 509 plat_lgrp_latency(lgrp_handle_t from, lgrp_handle_t to)
 510 {
 511         /*
 512          * Return min remote latency when there are more than two lgroups
 513          * (root and child) and getting latency between two different lgroups
 514          * or root is involved
 515          */
 516         if (lgrp_optimizations() && (from != to ||
 517             from == LGRP_DEFAULT_HANDLE || to == LGRP_DEFAULT_HANDLE))
 518                 return (21);
 519         else
 520                 return (19);
 521 }
 522 /*
 523  * No platform drivers on this platform
 524  */
 525 char *platform_module_list[] = {
 526         (char *)0
 527 };
 528 
 529 /*ARGSUSED*/
 530 void
 531 plat_tod_fault(enum tod_fault_type tod_bad)
 532 {
 533 }
 534 
 535 /*ARGSUSED*/
 536 int
 537 plat_get_mem_unum(int synd_code, uint64_t flt_addr, int flt_bus_id,
 538     int flt_in_memory, ushort_t flt_status, char *buf, int buflen, int *lenp)
 539 {
 540         if (flt_in_memory && (p2get_mem_unum != NULL))
 541                 return (p2get_mem_unum(synd_code, P2ALIGN(flt_addr, 8),
 542                     buf, buflen, lenp));
 543         else
 544                 return (ENOTSUP);
 545 }
 546 
 547 /*
 548  * This platform hook gets called from mc_add_mem_unum_label() in the mc-us3
 549  * driver giving each platform the opportunity to add platform
 550  * specific label information to the unum for ECC error logging purposes.
 551  */
 552 void
 553 plat_add_mem_unum_label(char *unum, int mcid, int bank, int dimm)
 554 {
 555         _NOTE(ARGUNUSED(bank, dimm))
 556 
 557         char board = DAK_GETSLOT_LABEL(mcid);
 558         char old_unum[UNUM_NAMLEN];
 559 
 560         (void) strcpy(old_unum, unum);
 561         (void) snprintf(unum, UNUM_NAMLEN, "Slot %c: %s", board, old_unum);
 562 }
 563 
 564 int
 565 plat_get_cpu_unum(int cpuid, char *buf, int buflen, int *lenp)
 566 {
 567         char board = DAK_GETSLOT_LABEL(cpuid);
 568 
 569         if (snprintf(buf, buflen, "Slot %c", board) >= buflen) {
 570                 return (ENOSPC);
 571         } else {
 572                 *lenp = strlen(buf);
 573                 return (0);
 574         }
 575 }
 576 
 577 /*
 578  * The zuluvm module required a dmv interrupt for each installed
 579  * Zulu/XVR-4000 board.  The following has not been updated during the
 580  * removal of zuluvm and therefore it may be suboptimal.
 581  */
 582 void
 583 plat_dmv_params(uint_t *hwint, uint_t *swint)
 584 {
 585         *hwint = 0;
 586         *swint = DAK_SBD_SLOTS - 1;
 587 }