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/ppc/m8260.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *      8260 specific stuff:
    3  *              Interrupt handling
    4  */
    5 #include        "u.h"
    6 #include        "../port/lib.h"
    7 #include        "mem.h"
    8 #include        "dat.h"
    9 #include        "io.h"
   10 #include        "fns.h"
   11 #include        "m8260.h"
   12 
   13 enum {
   14         Pin4 = BIT(4),
   15 };
   16 
   17 static union {
   18         struct {
   19                 ulong   hi;
   20                 ulong   lo;
   21         };
   22         uvlong          val;
   23 } ticks;
   24 
   25 struct {
   26         ulong   hi;
   27         ulong   lo;
   28 } vec2mask[64]  = {
   29 [0]     = {0,           0       },      /* Error, No interrupt */
   30 [1]     = {0,           BIT(16) },      /* I2C */
   31 [2]     = {0,           BIT(17) },      /* SPI */
   32 [3]     = {0,           BIT(18) },      /* Risc Timers */
   33 [4]     = {0,           BIT(19) },      /* SMC1 */
   34 [5]     = {0,           BIT(20) },      /* SMC2 */
   35 [6]     = {0,           BIT(21) },      /* IDMA1 */
   36 [7]     = {0,           BIT(22) },      /* IDMA2 */
   37 [8]     = {0,           BIT(23) },      /* IDMA3 */
   38 [9]     = {0,           BIT(24) },      /* IDMA4 */
   39 [10]    = {0,           BIT(25) },      /* SDMA */
   40 [11]    = {0,           0       },      /* Reserved */
   41 [12]    = {0,           BIT(27) },      /* Timer1 */
   42 [13]    = {0,           BIT(28) },      /* Timer2 */
   43 [14]    = {0,           BIT(29) },      /* Timer3 */
   44 [15]    = {0,           BIT(30) },      /* Timer4 */
   45 
   46 [16]    = {BIT(29),     0       },      /* TMCNT */
   47 [17]    = {BIT(30),     0       },      /* PIT */
   48 [18]    = {0,           0       },      /* Reserved */
   49 [19]    = {BIT(17),     0       },      /* IRQ1 */
   50 [20]    = {BIT(18),     0       },      /* IRQ2 */
   51 [21]    = {BIT(19),     0       },      /* IRQ3 */
   52 [22]    = {BIT(20),     0       },      /* IRQ4 */
   53 [23]    = {BIT(21),     0       },      /* IRQ5 */
   54 [24]    = {BIT(22),     0       },      /* IRQ6 */
   55 [25]    = {BIT(23),     0       },      /* IRQ7 */
   56 [26]    = {0,           0       },      /* Reserved */
   57 [27]    = {0,           0       },      /* Reserved */
   58 [28]    = {0,           0       },      /* Reserved */
   59 [29]    = {0,           0       },      /* Reserved */
   60 [30]    = {0,           0       },      /* Reserved */
   61 [31]    = {0,           0       },      /* Reserved */
   62 
   63 [32]    = {0,           BIT(0)  },      /* FCC1 */
   64 [33]    = {0,           BIT(1)  },      /* FCC2 */
   65 [34]    = {0,           BIT(2)  },      /* FCC3 */
   66 [35]    = {0,           0       },      /* Reserved */
   67 [36]    = {0,           BIT(4)  },      /* MCC1 */
   68 [37]    = {0,           BIT(5)  },      /* MCC2 */
   69 [38]    = {0,           0       },      /* Reserved */
   70 [39]    = {0,           0       },      /* Reserved */
   71 [40]    = {0,           BIT(8)  },      /* SCC1 */
   72 [41]    = {0,           BIT(9)  },      /* SCC2 */
   73 [42]    = {0,           BIT(10) },      /* SCC3 */
   74 [43]    = {0,           BIT(11) },      /* SCC4 */
   75 [44]    = {0,           0       },      /* Reserved */
   76 [45]    = {0,           0       },      /* Reserved */
   77 [46]    = {0,           0       },      /* Reserved */
   78 [47]    = {0,           0       },      /* Reserved */
   79 
   80 [48]    = {BIT(15),     0       },      /* PC15 */
   81 [49]    = {BIT(14),     0       },      /* PC14 */
   82 [50]    = {BIT(13),     0       },      /* PC13 */
   83 [51]    = {BIT(12),     0       },      /* PC12 */
   84 [52]    = {BIT(11),     0       },      /* PC11 */
   85 [53]    = {BIT(10),     0       },      /* PC10 */
   86 [54]    = {BIT(9),      0       },      /* PC9 */
   87 [55]    = {BIT(8),      0       },      /* PC8 */
   88 [56]    = {BIT(7),      0       },      /* PC7 */
   89 [57]    = {BIT(6),      0       },      /* PC6 */
   90 [58]    = {BIT(5),      0       },      /* PC5 */
   91 [59]    = {BIT(4),      0       },      /* PC4 */
   92 [60]    = {BIT(3),      0       },      /* PC3 */
   93 [61]    = {BIT(2),      0       },      /* PC2 */
   94 [62]    = {BIT(1),      0       },      /* PC1 */
   95 [63]    = {BIT(0),      0       },      /* PC0 */
   96 };
   97 
   98 /* Blast memory layout:
   99  *      CS0: FE000000 -> FFFFFFFF (Flash)
  100  *      CS1: FC000000 -> FCFFFFFF (DSP hpi)
  101  *      CS2: 00000000 -> 03FFFFFF (60x sdram)
  102  *      CS3: 04000000 -> 04FFFFFF (FPGA)
  103  *      CS4: 05000000 -> 06FFFFFF (local bus sdram)
  104  *      CS5: 07000000 -> 0700FFFF (eeprom - not populated)
  105  *      CS6: E0000000 -> E0FFFFFF (FPGA - 64bits)
  106  *
  107  * Main Board memory layout:
  108  *      CS0: FE000000 -> FEFFFFFF (16 M FLASH)
  109  *      CS1: FC000000 -> FCFFFFFF (16 M DSP1)
  110  *      CS2: 00000000 -> 03FFFFFF (64 M SDRAM)
  111  *      CS3: 04000000 -> 04FFFFFF (16M DSP2)
  112  *      CS4: 05000000 -> 06FFFFFF (32 M Local SDRAM)
  113  *      CS5: 07000000 -> 0700FFFF (eeprom - not populated)
  114  *      CS6: unused
  115  *      CS7: E0000000 -> E0FFFFFF (16 M FPGA)
  116  */
  117 
  118 IMM* iomem = (IMM*)IOMEM;
  119 
  120 static Lock cpmlock;
  121 
  122 void
  123 machinit(void)
  124 {
  125         ulong scmr;
  126         int pllmf;
  127         extern char* plan9inistr;
  128 
  129         memset(m, 0, sizeof(*m));
  130         m->cputype = getpvr()>>16;      /* pvr = 0x00810101 for the 8260 */
  131         m->imap = (Imap*)INTMEM;
  132 
  133         m->loopconst = 1096;
  134 
  135         /* Make sure Ethernet is disabled (boot code may have buffers allocated anywhere in memory) */
  136         iomem->fcc[0].gfmr &= ~(BIT(27)|BIT(26));
  137         iomem->fcc[1].gfmr &= ~(BIT(27)|BIT(26));
  138         iomem->fcc[2].gfmr &= ~(BIT(27)|BIT(26));
  139 
  140         /* Flashed CS configuration is wrong for DSP2.  It's set to 64 bits, should be 16 */
  141         iomem->bank[3].br = 0x04001001; /* Set 16-bit port */
  142 
  143         /*
  144          * FPGA is capable of doing 64-bit transfers.  To use these, set br to 0xe0000001.
  145          * Currently we use 32-bit transfers, because the 8260 does not easily do 64-bit operations.
  146          */
  147         iomem->bank[6].br = 0xe0001801;
  148         iomem->bank[6].or = 0xff000830; /* Was 0xff000816 */
  149 
  150 /*
  151  * All systems with rev. A.1 (0K26N) silicon had serious problems when doing
  152  * DMA transfers with data cache enabled (usually this shows when  using
  153  * one of the FCC's with some traffic on the ethernet).  Allocating FCC buffer
  154  * descriptors in main memory instead of DP ram solves this problem.
  155  */
  156 
  157         /* Guess at clocks based upon the PLL configuration from the
  158          * power-on reset.
  159          */
  160         scmr = iomem->scmr;
  161 
  162         /* The EST8260 is typically run using either 33 or 66 MHz
  163          * external clock.  The configuration byte in the Flash will
  164          * tell us which is configured.  The blast appears to be slightly
  165          * overclocked at 72 MHz (if set to 66 MHz, the uart runs too fast)
  166          */
  167 
  168         m->clkin = CLKIN;
  169 
  170         pllmf = scmr & 0xfff;
  171 
  172         /* This is arithmetic from the 8260 manual, section 9.4.1. */
  173 
  174         /* Collect the bits from the scmr.
  175         */
  176         m->vco_out = m->clkin * (pllmf + 1);
  177         if (scmr & BIT(19))     /* plldf (division factor is 1 or 2) */
  178                 m->vco_out >>= 1;
  179 
  180         m->cpmhz = m->vco_out >> 1;     /* cpm hz is half of vco_out */
  181         m->brghz = m->vco_out >> (2 * ((iomem->sccr & 0x3) + 1));
  182         m->bushz = m->vco_out / (((scmr & 0x00f00000) >> 20) + 1);
  183 
  184         /* Serial init sets BRG clock....I don't know how to compute
  185          * core clock from core configuration, but I think I know the
  186          * mapping....
  187          */
  188         switch(scmr >> (31-7)){
  189         case 0x0a:
  190                 m->cpuhz = m->clkin * 2;
  191                 break;
  192         case 0x0b:
  193                 m->cpuhz = (m->clkin >> 1) * 5;
  194                 break;
  195         default:
  196         case 0x0d:
  197                 m->cpuhz = m->clkin * 3;
  198                 break;
  199         case 0x14:
  200                 m->cpuhz = (m->clkin >> 1) * 7;
  201                 break;
  202         case 0x1c:
  203                 m->cpuhz = m->clkin * 4;
  204                 break;
  205         }
  206 
  207         m->cyclefreq = m->bushz / 4;
  208 
  209 /*      Expect:
  210         intfreq 133             m->cpuhz
  211         busfreq 33              m->bushz
  212         cpmfreq 99              m->cpmhz
  213         brgfreq 49.5            m->brghz
  214         vco             198
  215 */
  216 
  217         active.machs = 1;
  218         active.exiting = 0;
  219 
  220         putmsr(getmsr() | MSR_ME);
  221 
  222         /*
  223          * turn on data cache before instruction cache;
  224          * for some reason which I don't understand,
  225          * you can't turn on both caches at once
  226          */
  227         icacheenb();
  228         dcacheenb();
  229 
  230         kfpinit();
  231 
  232         /* Plan9.ini location in flash is FLASHMEM+PLAN9INI
  233          * if PLAN9INI == ~0, it's not stored in flash or there is no flash
  234          * if *cp == 0xff, flash memory is not initialized
  235          */
  236         if (PLAN9INI == ~0 || *(plan9inistr = (char*)(FLASHMEM+PLAN9INI)) == 0xff){
  237                 /* No plan9.ini in flash */
  238                 plan9inistr =
  239                         "console=0\n"
  240                         "ether0=type=fcc port=0 ea=00601d051dd8\n"
  241                         "flash0=mem=0xfe000000\n"
  242                         "fs=135.104.9.42\n"
  243                         "auth=135.104.9.7\n"
  244                         "authdom=cs.bell-labs.com\n"
  245                         "sys=blast\n"
  246                         "ntp=135.104.9.52\n";
  247         }
  248 }
  249 
  250 void
  251 fpgareset(void)
  252 {
  253         print("fpga reset\n");
  254 
  255         ioplock();
  256 
  257         iomem->port[1].pdat &= ~Pin4;   /* force reset signal to 0 */
  258         delay(100);
  259         iomem->port[1].pdat |= Pin4;            /* force reset signal back to one */
  260 
  261         iopunlock();
  262 }
  263 
  264 void
  265 hwintrinit(void)
  266 {
  267         iomem->sicr = 2 << 8;
  268         /* Write ones into most bits of the interrupt pending registers to clear interrupts */
  269         iomem->sipnr_h = ~7;
  270         iomem->sipnr_h = ~1;
  271         /* Clear the interrupt masks, thereby disabling all interrupts */
  272         iomem->simr_h = 0;
  273         iomem->simr_l = 0;
  274 
  275         iomem->sypcr &= ~2;     /* cause a machine check interrupt on memory timeout */
  276 
  277         /* Initialize fpga reset pin */
  278         iomem->port[1].pdir |= Pin4;            /* 1 is an output */
  279         iomem->port[1].ppar &= ~Pin4;
  280         iomem->port[1].pdat |= Pin4;            /* force reset signal back to one */
  281 }
  282 
  283 int
  284 vectorenable(Vctl *v)
  285 {
  286         ulong hi, lo;
  287 
  288         if (v->irq & ~0x3f){
  289                 print("m8260enable: interrupt vector %d out of range\n", v->irq);
  290                 return -1;
  291         }
  292         hi = vec2mask[v->irq].hi;
  293         lo = vec2mask[v->irq].lo;
  294         if (hi == 0 && lo == 0){
  295                 print("m8260enable: nonexistent vector %d\n", v->irq);
  296                 return -1;
  297         }
  298         ioplock();
  299         /* Clear the interrupt before enabling */
  300         iomem->sipnr_h |= hi;
  301         iomem->sipnr_l |= lo;
  302         /* Enable */
  303         iomem->simr_h |= hi;
  304         iomem->simr_l |= lo;
  305         iopunlock();
  306         return v->irq;
  307 }
  308 
  309 void
  310 vectordisable(Vctl *v)
  311 {
  312         ulong hi, lo;
  313 
  314         if (v->irq & ~0x3f){
  315                 print("m8260disable: interrupt vector %d out of range\n", v->irq);
  316                 return;
  317         }
  318         hi = vec2mask[v->irq].hi;
  319         lo = vec2mask[v->irq].lo;
  320         if (hi == 0 && lo == 0){
  321                 print("m8260disable: nonexistent vector %d\n", v->irq);
  322                 return;
  323         }
  324         ioplock();
  325         iomem->simr_h &= ~hi;
  326         iomem->simr_l &= ~lo;
  327         iopunlock();
  328 }
  329 
  330 int
  331 intvec(void)
  332 {
  333         return iomem->sivec >> 26;
  334 }
  335 
  336 void
  337 intend(int vno)
  338 {
  339         /* Clear interrupt */
  340         ioplock();
  341         iomem->sipnr_h |= vec2mask[vno].hi;
  342         iomem->sipnr_l |= vec2mask[vno].lo;
  343         iopunlock();
  344 }
  345 
  346 int
  347 m8260eoi(int)
  348 {
  349         return 0;
  350 }
  351 
  352 int
  353 m8260isr(int)
  354 {
  355         return 0;
  356 }
  357 
  358 void
  359 flashprogpower(int)
  360 {
  361 }
  362 
  363 enum {
  364         TgcrCas                         = 0x80,
  365         TgcrGm                  = 0x08,
  366         TgcrStp                         = 0x2,  /* There are two of these, timer-2 bits are bits << 4 */
  367         TgcrRst                         = 0x1,
  368 
  369         TmrIclkCasc             = 0x00<<1,
  370         TmrIclkIntclock = 0x01<<1,
  371         TmrIclkIntclock16       = 0x02<<1,
  372         TmrIclkTin              = 0x03<<1,
  373         TmrCERising             = 0x1 << 6,
  374         TmrCEFalling            = 0x2 << 6,
  375         TmrCEAny                = 0x3 << 6,
  376         TmrFrr                  = SBIT(12),
  377         TmrOri                  = SBIT(11),
  378 
  379         TerRef                  = SBIT(14),
  380         TerCap                  = SBIT(15),
  381 };
  382 
  383 uvlong
  384 fastticks(uvlong *hz)
  385 {
  386         ulong count;
  387         static Lock fasttickslock;
  388 
  389         if (hz)
  390                 *hz = m->clkin>>1;
  391         ilock(&fasttickslock);
  392         count = iomem->tcnl1;
  393         if (count < ticks.lo)
  394                 ticks.hi += 1;
  395         ticks.lo = count;
  396         iunlock(&fasttickslock);
  397         return ticks.val;
  398 }
  399 
  400 void
  401 timerset(uvlong next)
  402 {
  403         long offset;
  404         uvlong now;
  405         static int cnt;
  406 
  407         now = fastticks(nil);
  408         offset = next - now;
  409         if (offset < 2500)
  410                 next = now + 2500;      /* 10000 instructions */
  411         else if (offset > m->clkin / HZ){
  412                 print("too far in the future: offset %llux, now %llux\n", next, now);
  413                 next = now + m->clkin / HZ;
  414         }
  415         iomem->trrl1 = next;
  416 }
  417 
  418 void
  419 m8260timerintr(Ureg *u, void*)
  420 {
  421         iomem->ter2 |= TerRef | TerCap;         /* Clear interrupt */
  422         timerintr(u, 0);
  423 }
  424 
  425 void
  426 timerinit(void)
  427 {
  428 
  429         iomem->tgcr1 = TgcrCas | TgcrGm;                /* cascade timers 1 & 2, normal gate mode */
  430         iomem->tcnl1 = 0;
  431         iomem->trrl1 = m->clkin / HZ;           /* first capture in 1/HZ seconds */
  432         iomem->tmr1 = TmrIclkCasc;
  433         iomem->tmr2 = TmrIclkIntclock | TmrOri;
  434         intrenable(13, m8260timerintr, nil, "timer");   /* Timer 2 interrupt is on 13 */
  435         iomem->tgcr1 |= TgcrRst << 4;
  436 }
  437 
  438 static void
  439 addseg(char *name, ulong start, ulong length)
  440 {
  441         Physseg segbuf;
  442 
  443         memset(&segbuf, 0, sizeof(segbuf));
  444         segbuf.attr = SG_PHYSICAL;
  445         kstrdup(&segbuf.name, name);
  446         segbuf.pa = start;
  447         segbuf.size = length;
  448         if (addphysseg(&segbuf) == -1) {
  449                 print("addphysseg: %s\n", name);
  450                 return;
  451         }
  452 }
  453 
  454 void
  455 sharedseginit(void)
  456 {
  457         int i, j;
  458         ulong base, size;
  459         char name[16], *a, *b, *s;
  460         static char *segnames[] = {
  461                 "fpga",
  462                 "dsp",
  463         };
  464 
  465         for (j = 0; j < nelem(segnames); j++){
  466                 for (i = 0; i < 8; i++){
  467                         snprint(name, sizeof name, "%s%d", segnames[j], i);
  468                         if ((a = getconf(name)) == nil)
  469                                 continue;
  470                         if ((b = strstr(a, "mem=")) == nil){
  471                                 print("blastseginit: %s: no base\n", name);
  472                                 continue;
  473                         }
  474                         b += 4;
  475                         base = strtoul(b, nil, 0);
  476                         if (base == 0){
  477                                 print("blastseginit: %s: bad base: %s\n", name, b);
  478                                 continue;
  479                         }
  480                         if ((s = strstr(a, "size=")) == nil){
  481                                 print("blastseginit: %s: no size\n", name);
  482                                 continue;
  483                         }
  484                         s += 5;
  485                         size = strtoul(s, nil, 0);
  486                         if (size == 0){
  487                                 print("blastseginit: %s: bad size: %s\n", name, s);
  488                                 continue;
  489                         }
  490                         addseg(name, base, size);
  491                 }
  492         }
  493 }
  494 
  495 void
  496 cpmop(int op, int dev, int mcn)
  497 {
  498         ioplock();
  499         eieio();
  500         while(iomem->cpcr & 0x10000)
  501                 eieio();
  502         iomem->cpcr = dev<<(31-10) | mcn<<(31-25) | op | 0x10000;
  503         eieio();
  504         while(iomem->cpcr & 0x10000)
  505                 eieio();
  506         iopunlock();
  507 }
  508 
  509 /*
  510  * connect SCCx clocks in NSMI mode (x=1 for USB)
  511  */
  512 void
  513 sccnmsi(int x, int rcs, int tcs)
  514 {
  515         ulong v;
  516         int sh;
  517 
  518         sh = (x-1)*8;   /* each SCCx field in sicr is 8 bits */
  519         v = (((rcs&7)<<3) | (tcs&7)) << sh;
  520         iomem->sicr = (iomem->sicr & ~(0xFF<<sh)) | v;
  521 }
  522 
  523 /*
  524  * lock the shared IO memory and return a reference to it
  525  */
  526 void
  527 ioplock(void)
  528 {
  529         ilock(&cpmlock);
  530 }
  531 
  532 /*
  533  * release the lock on the shared IO memory
  534  */
  535 void
  536 iopunlock(void)
  537 {
  538         eieio();
  539         iunlock(&cpmlock);
  540 }
  541 
  542 BD*
  543 bdalloc(int n)
  544 {
  545         static BD *palloc = ((Imap*)INTMEM)->bd;
  546         BD *p;
  547         
  548         p = palloc;
  549         if (palloc > ((Imap*)INTMEM)->bd + nelem(((Imap*)INTMEM)->bd)){
  550                 print("bdalloc: out of BDs\n");
  551                 return nil;
  552         }
  553         palloc += n;
  554         return p;
  555 }
  556 
  557 /*
  558  * Initialise receive and transmit buffer rings.  Only used for FCC
  559  * Ethernet now.
  560  *
  561  * Ioringinit will allocate the buffer descriptors in normal memory
  562  * and NOT in Dual-Ported Ram, as prescribed by the MPC8260
  563  * PowerQUICC II manual (Section 28.6).  When they are allocated
  564  * in DPram and the Dcache is enabled, the processor will hang.
  565  * This has been observed for the FCCs, it may or may not be true
  566  * for SCCs or DMA.
  567  * The SMC Uart buffer descriptors are not allocated here; (1) they
  568  * can ONLY be in DPram and (2) they are not configured as a ring.
  569  */
  570 int
  571 ioringinit(Ring* r, int nrdre, int ntdre, int bufsize)
  572 {
  573         int i, x;
  574         static uchar *dpmallocaddr;
  575         static uchar *dpmallocend;
  576 
  577         if (dpmallocaddr == nil){
  578                 dpmallocaddr = m->imap->dpram1;
  579                 dpmallocend = dpmallocaddr + sizeof(m->imap->dpram1);
  580         }
  581         /* the ring entries must be aligned on sizeof(BD) boundaries */
  582         r->nrdre = nrdre;
  583         if(r->rdr == nil)
  584                 r->rdr = xspanalloc(nrdre*sizeof(BD), 0, 8);
  585         if(r->rdr == nil)
  586                 return -1;
  587         if(r->rrb == nil && bufsize){
  588                 r->rrb = xspanalloc(nrdre*bufsize, 0, CACHELINESZ);
  589                 if(r->rrb == nil)
  590                         return -1;
  591         }
  592         x = bufsize ? PADDR(r->rrb) : 0;
  593         for(i = 0; i < nrdre; i++){
  594                 r->rdr[i].length = 0;
  595                 r->rdr[i].addr = x;
  596                 r->rdr[i].status = BDEmpty|BDInt;
  597                 x += bufsize;
  598         }
  599         r->rdr[i-1].status |= BDWrap;
  600         r->rdrx = 0;
  601 
  602         r->ntdre = ntdre;
  603         if(r->tdr == nil)
  604                 r->tdr = xspanalloc(ntdre*sizeof(BD), 0, 8);
  605         if(r->txb == nil)
  606                 r->txb = xspanalloc(ntdre*sizeof(Block*), 0, CACHELINESZ);
  607         if(r->tdr == nil || r->txb == nil)
  608                 return -1;
  609         for(i = 0; i < ntdre; i++){
  610                 r->txb[i] = nil;
  611                 r->tdr[i].addr = 0;
  612                 r->tdr[i].length = 0;
  613                 r->tdr[i].status = 0;
  614         }
  615         r->tdr[i-1].status |= BDWrap;
  616         r->tdrh = 0;
  617         r->tdri = 0;
  618         r->ntq = 0;
  619         return 0;
  620 }
  621 
  622 void
  623 trapinit(void)
  624 {
  625         int i;
  626 
  627         /*
  628          * set all exceptions to trap
  629          */
  630         for(i = 0x0; i < 0x2000; i += 0x100)
  631                 sethvec(i, trapvec);
  632 
  633         setmvec(0x1000, imiss, tlbvec);
  634         setmvec(0x1100, dmiss, tlbvec);
  635         setmvec(0x1200, dmiss, tlbvec);
  636 
  637 /*      Useful for avoiding assembler miss handling:
  638         sethvec(0x1000, tlbvec);
  639         sethvec(0x1100, tlbvec);
  640         sethvec(0x1200, tlbvec);
  641 /* */
  642         dcflush(KADDR(0), 0x2000);
  643         icflush(KADDR(0), 0x2000);
  644 
  645         putmsr(getmsr() & ~MSR_IP);
  646 }
  647 
  648 void
  649 reboot(void*, void*, ulong)
  650 {
  651         ulong *p;
  652         int x;
  653 
  654         p = (ulong*)0x90000000;
  655         x = splhi();
  656         iomem->sypcr |= 0xc0;
  657         print("iomem->sypcr = 0x%lux\n", iomem->sypcr);
  658         *p = 0;
  659         print("still alive\n");
  660         splx(x);
  661 }

Cache object: 0c1e9c54904f01710a48a6eded714329


[ 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.