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/bitsy/power.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 #include        "u.h"
    2 #include        "../port/lib.h"
    3 #include        "mem.h"
    4 #include        "dat.h"
    5 #include        "fns.h"
    6 #include        "io.h"
    7 #include        "ureg.h"
    8 #include        "pool.h"
    9 
   10 /* Power management for the bitsy */
   11 
   12 #define TODFREQ 1000000000LL
   13 
   14 /* saved state during power down. 
   15  * it's only used up to 164/4.
   16  * it's only used by routines in l.s
   17  */
   18 ulong   power_state[200/4];
   19 
   20 ulong   resumeaddr[1];
   21 Rendez  powerr;
   22 ulong   powerflag = 0;  /* set to start power-off sequence */
   23 
   24 extern void     power_resume(void);
   25 extern int              setpowerlabel(void);
   26 extern void     _start(void);
   27 extern Uart     sa1110uart[];
   28 
   29 GPIOregs savedgpioregs;
   30 Intrregs savedintrregs;
   31 
   32 #define R(p) ((Uartregs*)((p)->regs))
   33 
   34 uchar *savedtext;
   35 
   36 static void
   37 checkflash(void)
   38 {
   39         ulong *p;
   40         ulong s;
   41 
   42         s = 0;
   43         for (p = (ulong*)FLASHZERO; p < (ulong*)(FLASHZERO+8*1024*1024); p++)
   44                 s += *p;
   45         iprint("flash checksum is 0x%lux\n", s);
   46 }
   47 
   48 static void
   49 checkktext(void)
   50 {
   51         ulong *p;
   52         ulong s;
   53 
   54         s = 0;
   55         for (p = (ulong*)_start; p < (ulong*)etext; p++){
   56                 if(*p == 0)
   57                         iprint("%#p->0\n", p);
   58                 if (((ulong)p & 0x1fff) == 0){
   59                         iprint("page 0x%lux checksum 0x%lux\n",
   60                                 (ulong)(p-1)&~0x1fff, s);
   61                         s = 0;
   62                 }
   63                 s += *p;
   64         }
   65         iprint("page 0x%lux checksum 0x%lux\n", (ulong)(p-1)&~0x1fff, s);
   66 }
   67 
   68 static void
   69 checkpagetab(void)
   70 {
   71         extern ulong l1table;
   72         ulong *p;
   73         ulong s;
   74 
   75         s = 0;
   76         for (p = (ulong*)l1table; p < (ulong*)(l1table+16*1024); p++)
   77                 s += *p;
   78         iprint("page table checksum is 0x%lux\n", s);
   79 }
   80 
   81 
   82 static void
   83 dumpitall(void)
   84 {
   85         extern ulong l1table;
   86 
   87         iprint("intr: icip %lux iclr %lux iccr %lux icmr %lux\n",
   88                 intrregs->icip,
   89                 intrregs->iclr, intrregs->iccr, intrregs->icmr );
   90         iprint("gpio: lvl %lux dir %lux, re %lux, fe %lux sts %lux alt %lux\n",
   91                 gpioregs->level,
   92                 gpioregs->direction, gpioregs->rising, gpioregs->falling,
   93                 gpioregs->edgestatus, gpioregs->altfunc);
   94         iprint("uart1: %lux %lux %lux \nuart3: %lux %lux %lux\n", 
   95                 R(&sa1110uart[0])->ctl[0], R(&sa1110uart[0])->status[0], R(&sa1110uart[0])->status[1], 
   96                 R(&sa1110uart[1])->ctl[0], R(&sa1110uart[1])->status[0], R(&sa1110uart[1])->status[1]); 
   97         iprint("tmr: osmr %lux %lux %lux %lux oscr %lux ossr %lux oier %lux\n",
   98                 timerregs->osmr[0], timerregs->osmr[1],
   99                 timerregs->osmr[2], timerregs->osmr[3],
  100                 timerregs->oscr, timerregs->ossr, timerregs->oier);
  101         iprint("dram: mdcnfg %lux mdrefr %lux cas %lux %lux %lux %lux %lux %lux\n",
  102                 memconfregs->mdcnfg, memconfregs->mdrefr,
  103                 memconfregs->mdcas00, memconfregs->mdcas01,memconfregs->mdcas02,
  104                 memconfregs->mdcas20, memconfregs->mdcas21,memconfregs->mdcas22); 
  105         iprint("dram: mdcnfg msc %lux %lux %lux mecr %lux\n",
  106                 memconfregs->msc0, memconfregs->msc1,memconfregs->msc2,
  107                 memconfregs->mecr);
  108         iprint("mmu: CpControl %lux CpTTB %lux CpDAC %lux l1table 0x%lux\n",
  109                 getcontrol(), getttb(), getdac(), l1table);
  110         iprint("powerregs: pmcr %lux pssr %lux pcfr %lux ppcr %lux pwer %lux pspr %lux pgsr %lux posr %lux\n",
  111                 powerregs->pmcr, powerregs->pssr, powerregs->pcfr, powerregs->ppcr,
  112                 powerregs->pwer, powerregs->pspr, powerregs->pgsr, powerregs->posr);
  113         checkpagetab();
  114         checkflash();
  115         checkktext();
  116         iprint("\n\n");
  117 }
  118 
  119 static void
  120 intrcpy(Intrregs *to, Intrregs *from)
  121 {
  122         to->iclr = from->iclr;
  123         to->iccr = from->iccr;
  124         to->icmr = from->icmr;  // interrupts enabled
  125 }
  126 
  127 static void
  128 gpiosave(GPIOregs *to, GPIOregs *from)
  129 {
  130         to->level = from->level;
  131         to->rising = from->rising;              // gpio intrs enabled
  132         to->falling= from->falling;             // gpio intrs enabled
  133         to->altfunc = from->altfunc;
  134         to->direction = from->direction;
  135 }
  136 
  137 static void
  138 gpiorestore(GPIOregs *to, GPIOregs *from)
  139 {
  140         to->direction = from->direction;
  141         to->altfunc = from->altfunc;
  142         to->set = from->level & 0x0fffffff;
  143         to->clear = ~from->level & 0x0fffffff;
  144         to->rising = from->rising;              // gpio intrs enabled
  145         to->falling= from->falling;             // gpio intrs enabled
  146 }
  147 
  148 void    (*restart)(void) = nil;
  149 
  150 static int
  151 bitno(ulong x)
  152 {
  153         int i;
  154 
  155         for(i = 0; i < 8*sizeof(x); i++)
  156                 if((1<<i) & x)
  157                         break;
  158         return i;
  159 }
  160 
  161 int
  162 powerdown(void *)
  163 {
  164         return powerflag;
  165 }
  166 
  167 void
  168 deepsleep(void) {
  169         static int power_pl;
  170         ulong xsp, xlink;
  171 //      ulong mecr;
  172         ulong clkd;
  173         vlong savedtod;
  174         extern void power_resume(void);
  175 
  176         power_pl = splhi();
  177         xlink = getcallerpc(&xlink);
  178 
  179         /* Power down */
  180         pcmciapower(0);
  181         irpower(0);
  182         audiopower(0);
  183         screenpower(0);
  184         µcpower(0);
  185         iprint("entering suspend mode, sp = %#p, pc = 0x%lux, psw = 0x%ux\n",
  186                 &xsp, xlink, power_pl);
  187 //      dumpitall();
  188         delay(1000);
  189         uartpower(0);
  190         rs232power(0);
  191         clockpower(0);
  192         gpiosave(&savedgpioregs, gpioregs);
  193         intrcpy(&savedintrregs, intrregs);
  194         cacheflush();
  195         delay(50);
  196         if(setpowerlabel()){
  197                 /* return here with mmu back on */
  198                 trapresume();
  199 
  200                 gpiorestore(gpioregs, &savedgpioregs);
  201                 delay(50);
  202                 intrcpy(intrregs, &savedintrregs);
  203                 if(intrregs->icip & (1<<IRQgpio0)){
  204                         // don't want to sleep now. clear on/off irq.
  205                         gpioregs->edgestatus = (1<<IRQgpio0);
  206                         intrregs->icip = (1<<IRQgpio0);
  207                 }
  208                 clkd = clockpower(1);
  209                 gpclkregs->r0 = 1<<0;
  210                 todset(savedtod + clkd * TODFREQ, 0LL, 0);
  211                 resetsuspendtimer();
  212                 rs232power(1);
  213                 uartpower(1);
  214                 delay(100);
  215                 xlink = getcallerpc(&xlink);
  216                 iprint("\nresuming execution, sp = %#p, pc = 0x%lux, psw = 0x%ux\n",
  217                         &xsp, xlink, splhi());
  218 //              dumpitall();
  219                 delay(1000);
  220 //              irpower(1);
  221                 audiopower(1);
  222                 µcpower(1);
  223                 screenpower(1);
  224                 pcmciapower(1);
  225                 splx(power_pl);
  226                 return;
  227         }
  228         cacheflush();
  229         delay(100);
  230         savedtod = todget(nil);
  231         power_down();
  232         /* no return */
  233 }
  234 
  235 void
  236 powerkproc(void*)
  237 {
  238         ulong xlink, xlink1;
  239 
  240         for(;;){
  241                 while(powerflag == 0)
  242                         sleep(&powerr, powerdown, 0);
  243 
  244                 xlink = getcallerpc(&xlink);
  245 
  246 //              iprint("call deepsleep, pc = 0x%lux, sp = 0x%lux\n", xlink, &xlink);
  247                 deepsleep();
  248                 xlink1 = getcallerpc(&xlink1);
  249 
  250 
  251                 delay(2000);
  252 
  253 //              iprint("deepsleep returned, pc = 0x%lux, sp = 0x%lux\n", xlink1, &xlink);
  254                 powerflag = 0;
  255         }
  256 }
  257 
  258 void
  259 onoffintr(Ureg* , void*)
  260 {
  261         int i;
  262 
  263         /* Power down interrupt comes on power button release.
  264          * Act only after button has been released a full 100 ms
  265          */
  266 
  267         if (powerflag)
  268                 return;
  269 
  270         for (i = 0; i < 100; i++) {
  271                 delay(1);
  272                 if ((gpioregs->level & GPIO_PWR_ON_i) == 0)
  273                         return; /* bounced */
  274         }
  275 
  276         powerflag = 1;
  277         wakeup(&powerr);
  278 }
  279 
  280 static void
  281 blanktimer(void)
  282 {
  283         drawactive(0);
  284 }
  285 
  286 static ulong suspendtime = 120 * HZ;
  287 static int lastsuspend;
  288 
  289 void
  290 resetsuspendtimer(void)
  291 {
  292         suspendtime = 60 * HZ;
  293 }
  294 
  295 static void
  296 suspendtimer(void)
  297 {
  298 #ifdef notdef
  299         uvlong  now;
  300 
  301         if (suspendtime > 0)
  302                 suspendtime--;
  303         if (suspendtime == 0){
  304                 now = seconds();
  305                 if (now < lastsuspend + 10){
  306                         resetsuspendtimer();
  307                         return;
  308                 }
  309                 lastsuspend = seconds();
  310                 deepsleep();
  311                 lastsuspend = seconds();
  312                 return;
  313         }
  314 #endif /* notdef */
  315 }
  316 
  317 void
  318 powerinit(void)
  319 {
  320         extern ulong power_magic;
  321         extern ulong power_code;
  322         extern ulong doze_code;
  323         ulong *p, *q, i;
  324 
  325         p = (ulong*)(((ulong)&power_magic + 0x1f) & ~0x1f);
  326         q = &power_code;
  327         for (i = 0; i < 8; i++)
  328                 *p++ = *q++;
  329         p = (ulong*)(((ulong)doze + 0x3f) & ~0x1f);
  330         q = &doze_code;
  331         for (i = 0; i < 3; i++)
  332                 *p++ = *q++;
  333 
  334         *resumeaddr = (ulong) power_resume;
  335         addclock0link(blanktimer, 1000/HZ);
  336         addclock0link(suspendtimer, 1000/HZ);
  337         intrenable(GPIOrising, bitno(GPIO_PWR_ON_i), onoffintr, nil, "on/off");
  338 }
  339 
  340 void
  341 idlehands(void)
  342 {
  343         char *msgb = "idlehands called with splhi\n";
  344         char *msga = "doze returns with splhi\n";
  345 
  346         if(!islo()){
  347                 uartputs(msga, strlen(msga));
  348                 spllo();
  349         }
  350         doze();
  351         if(!islo()){
  352                 uartputs(msgb, strlen(msgb));
  353                 spllo();
  354         }
  355 }
  356 

Cache object: e1156d99950b5c49ce564c33ebed8b5f


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