Home | History | Annotate | Line # | Download | only in common
      1  1.1     pooka /* Copyright (c) 1999 The NetBSD Foundation, Inc.
      2  1.1     pooka  * All rights reserved.
      3  1.1     pooka  *
      4  1.1     pooka  * Copyright (c) 2008 Microsoft.  All rights reserved.
      5  1.1     pooka  *
      6  1.1     pooka  * Redistribution and use in source and binary forms, with or without
      7  1.1     pooka  * modification, are permitted provided that the following conditions
      8  1.1     pooka  * are met:
      9  1.1     pooka  * 1. Redistributions of source code must retain the above copyright
     10  1.1     pooka  *    notice, this list of conditions and the following disclaimer.
     11  1.1     pooka  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1     pooka  *    notice, this list of conditions and the following disclaimer in the
     13  1.1     pooka  *    documentation and/or other materials provided with the distribution.
     14  1.1     pooka  *
     15  1.1     pooka  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     16  1.1     pooka  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     17  1.1     pooka  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     18  1.1     pooka  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     19  1.1     pooka  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20  1.1     pooka  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21  1.1     pooka  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22  1.1     pooka  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23  1.1     pooka  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24  1.1     pooka  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  1.1     pooka  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  1.1     pooka  * POSSIBILITY OF SUCH DAMAGE.
     27  1.1     pooka  */
     28  1.1     pooka 
     29  1.1     pooka #include <lib/libsa/stand.h>
     30  1.1     pooka #include <lib/libsa/loadfile.h>
     31  1.1     pooka #include <lib/libkern/libkern.h>
     32  1.1     pooka 
     33  1.1     pooka #include <sys/param.h>
     34  1.1     pooka #include <sys/exec.h>
     35  1.1     pooka #include <sys/exec_elf.h>
     36  1.1     pooka #include <sys/reboot.h>
     37  1.1     pooka 
     38  1.1     pooka #include <machine/emipsreg.h>
     39  1.1     pooka 
     40  1.1     pooka #include "common.h"
     41  1.1     pooka #include "bootinfo.h"
     42  1.1     pooka #include "start.h"
     43  1.1     pooka #include "prom_iface.h"
     44  1.1     pooka 
     45  1.1     pooka #if _DEBUG
     46  1.1     pooka #define TRACE(x) printf x
     47  1.1     pooka #else
     48  1.1     pooka #define TRACE(x)
     49  1.1     pooka #endif
     50  1.1     pooka 
     51  1.1     pooka void epmc_halt(void);
     52  1.1     pooka void save_locore(void);
     53  1.1     pooka void restore_locore(void);
     54  1.1     pooka 
     55  1.3  christos static void *nope(void) {return NULL;}
     56  1.1     pooka int getchar(void){return GetChar();}
     57  1.1     pooka 
     58  1.3  christos static void
     59  1.3  christos real_halt(void *arg)
     60  1.1     pooka {
     61  1.1     pooka     int howto = (int)arg;
     62  1.1     pooka     u_int ps = GetPsr();
     63  1.1     pooka 
     64  1.1     pooka     /* Turn off interrupts and the TLB */
     65  1.1     pooka #define EMIPS_SR_RP  0x08000000  /* reduced power */
     66  1.1     pooka #define EMIPS_SR_TS  0x00200000  /* TLB shutdown  */
     67  1.1     pooka #define EMIPS_SR_RST 0x00000080  /* Soft-reset    */
     68  1.1     pooka #define EMIPS_SR_INT 0x0000ff00  /* Interrupt enable mask */
     69  1.1     pooka #define EMIPS_SR_IEc 0x00000001  /* Interrupt enable current */
     70  1.1     pooka 
     71  1.1     pooka     ps &= ~(EMIPS_SR_INT | EMIPS_SR_IEc);
     72  1.1     pooka     ps |= EMIPS_SR_TS;
     73  1.1     pooka     SetPsr(ps);
     74  1.1     pooka 
     75  1.1     pooka     /* Reset entry must be restored for reboot
     76  1.1     pooka      */
     77  1.1     pooka     restore_locore();
     78  1.1     pooka 
     79  1.1     pooka     /* Tell the power manager to halt? */
     80  1.1     pooka     for (;howto & RB_HALT;) {
     81  1.1     pooka         epmc_halt();
     82  1.1     pooka 
     83  1.1     pooka         /* We should not be here!! */
     84  1.1     pooka         ps |= EMIPS_SR_RP | EMIPS_SR_INT; /* but not current */
     85  1.1     pooka         SetPsr(ps);
     86  1.1     pooka     }
     87  1.1     pooka 
     88  1.1     pooka     /* For a reboot, all we can really do is a reset actually */
     89  1.1     pooka     for (;;) {
     90  1.1     pooka         ps |= EMIPS_SR_RST;
     91  1.1     pooka         SetPsr(ps);
     92  1.1     pooka     }
     93  1.1     pooka }
     94  1.1     pooka 
     95  1.3  christos static void
     96  1.3  christos halt(int *unused, int howto)
     97  1.1     pooka {
     98  1.1     pooka     /* We must switch to a safe stack! TLB will go down
     99  1.1     pooka      */
    100  1.1     pooka     switch_stack_and_call((void *)howto,real_halt);
    101  1.1     pooka     /* no return, stack lost */
    102  1.1     pooka }
    103  1.1     pooka 
    104  1.1     pooka struct callback cb = {
    105  1.1     pooka     nope,
    106  1.1     pooka     nope,
    107  1.1     pooka     nope,
    108  1.1     pooka     nope,
    109  1.1     pooka     nope,
    110  1.1     pooka     nope,
    111  1.1     pooka     nope,
    112  1.1     pooka     nope,
    113  1.1     pooka     nope,
    114  1.3  christos     getchar,
    115  1.1     pooka     nope,
    116  1.1     pooka     nope,
    117  1.3  christos     printf,
    118  1.1     pooka     nope,
    119  1.1     pooka     nope,
    120  1.1     pooka     nope,
    121  1.1     pooka     nope,
    122  1.1     pooka     nope,
    123  1.1     pooka     nope,
    124  1.1     pooka     nope,
    125  1.1     pooka     nope,
    126  1.1     pooka     nope,
    127  1.1     pooka     nope,
    128  1.1     pooka     nope,
    129  1.1     pooka     nope,
    130  1.1     pooka     nope,
    131  1.1     pooka     nope,
    132  1.1     pooka     nope,
    133  1.1     pooka     nope,
    134  1.1     pooka     nope,
    135  1.1     pooka     nope,
    136  1.1     pooka     nope,
    137  1.1     pooka     getsysid,
    138  1.1     pooka     nope,
    139  1.1     pooka     nope,
    140  1.1     pooka     nope,
    141  1.1     pooka     nope,
    142  1.1     pooka     nope,
    143  1.1     pooka     nope,
    144  1.3  christos     halt
    145  1.1     pooka };
    146  1.1     pooka 
    147  1.1     pooka typedef char *string_t;
    148  1.1     pooka 
    149  1.1     pooka void epmc_halt(void)
    150  1.1     pooka {
    151  1.1     pooka     struct _Pmc *pm = (struct _Pmc *)0xfff00000;
    152  1.1     pooka 
    153  1.1     pooka     pm->SystemPowerDisable = PMCSC_CPU;
    154  1.1     pooka }
    155  1.1     pooka 
    156  1.1     pooka 
    157  1.1     pooka int init_usart(void)
    158  1.1     pooka {
    159  1.1     pooka     struct _Usart *us = (struct _Usart *)0xfff90000;
    160  1.1     pooka 
    161  1.1     pooka     us->Baud = 0x29;
    162  1.1     pooka     us->Control = (USC_RXEN|USC_TXEN|USC_BPC_8|USC_NONE|USC_1STOP|USC_CLKDIV_4);
    163  1.1     pooka     return 1;
    164  1.1     pooka }
    165  1.1     pooka 
    166  1.1     pooka /* Need to scan the PMT for all memory controllers
    167  1.1     pooka  * Actually.. just enough to make the kernel fit but we dont know how big it is
    168  1.1     pooka  */
    169  1.1     pooka 
    170  1.1     pooka /* Common format for SRAM, DDRAM, and FLASH controllers.
    171  1.1     pooka  * Use SRAM decl. and careful about DDRAM that is twice as big.
    172  1.1     pooka  */
    173  1.1     pooka typedef struct _Sram *ram_controller_t;
    174  1.1     pooka # define                RAMBT_TAG   SRAMBT_TAG
    175  1.1     pooka # define                RAMBT_BASE  SRAMBT_BASE
    176  1.1     pooka # define                RAMST_SIZE  SRAMST_SIZE
    177  1.1     pooka 
    178  1.1     pooka int init_memory(void)
    179  1.1     pooka {
    180  1.1     pooka     struct _Pmt *Pmt;
    181  1.1     pooka     ram_controller_t Ram, Ours, First;
    182  1.1     pooka     uint32_t base, addr, moi = (uint32_t)(&init_memory) & 0x3ffff000;
    183  1.1     pooka     size_t size;
    184  1.1     pooka     uint16_t tag;
    185  1.1     pooka     int nsr, ndr, nfl;
    186  1.1     pooka 
    187  1.1     pooka     /* Make three passes.
    188  1.1     pooka      * First find which controller we are running under, cuz we cant touch it.
    189  1.1     pooka      * Then remap every RAM segment around it.
    190  1.1     pooka      * Then make sure FLASH segments do not overlap RAM.
    191  1.1     pooka      */
    192  1.1     pooka 
    193  1.1     pooka     nsr = ndr = nfl = 0;
    194  1.1     pooka     First = Ours = NULL;
    195  1.1     pooka     base = ~0;
    196  1.1     pooka     for (Pmt = ThePmt;;Pmt--) {
    197  1.1     pooka         tag = Pmt->Tag;
    198  1.1     pooka         //printf("PMT @%x tag=%x\n",Pmt,tag);
    199  1.1     pooka         switch (tag) {
    200  1.1     pooka         case PMTTAG_END_OF_TABLE:
    201  1.1     pooka             goto DoneFirst;
    202  1.1     pooka         case PMTTAG_SRAM:
    203  1.1     pooka         case PMTTAG_DDRAM:
    204  1.1     pooka         case PMTTAG_FLASH:
    205  1.1     pooka             Ram = (ram_controller_t)(Pmt->TopOfPhysicalAddress << 16);
    206  1.1     pooka             /* Scan the whole segment */
    207  1.1     pooka             for (;;) {
    208  1.1     pooka                 //printf("RAM @%x tag=%x ctl=%x\n", Ram, Ram->BaseAddressAndTag,Ram->Control);
    209  1.1     pooka                 if (tag != (Ram->BaseAddressAndTag & RAMBT_TAG))
    210  1.1     pooka                     break;
    211  1.1     pooka                 addr = Ram->BaseAddressAndTag & RAMBT_BASE;
    212  1.1     pooka                 if ((tag != PMTTAG_FLASH) && (addr < base)) {
    213  1.1     pooka                     base = addr;
    214  1.1     pooka                     First = Ram;
    215  1.1     pooka                 }
    216  1.1     pooka                 size = Ram->Control & RAMST_SIZE;
    217  1.1     pooka                 if ((moi >= addr) && (moi < (addr + size))) {
    218  1.1     pooka                     Ours = Ram;
    219  1.1     pooka                 }
    220  1.1     pooka                 /* Next one.. and count them */
    221  1.1     pooka                 Ram++;
    222  1.1     pooka                 switch (tag) {
    223  1.1     pooka                 case PMTTAG_SRAM:
    224  1.1     pooka                     nsr++;
    225  1.1     pooka                     break;
    226  1.1     pooka                 case PMTTAG_FLASH:
    227  1.1     pooka                     nfl++;
    228  1.1     pooka                     break;
    229  1.1     pooka                 case PMTTAG_DDRAM:
    230  1.1     pooka                     Ram++; /* yeach */
    231  1.1     pooka                     ndr++;
    232  1.1     pooka                     break;
    233  1.1     pooka                 }
    234  1.1     pooka             }
    235  1.1     pooka             break;
    236  1.1     pooka         default:
    237  1.1     pooka             break;
    238  1.1     pooka         }
    239  1.1     pooka     }
    240  1.1     pooka 
    241  1.1     pooka     /* Make sure we know */
    242  1.1     pooka  DoneFirst:
    243  1.1     pooka     if ((First == NULL) || (Ours == NULL)) {
    244  1.3  christos         printf("Bad memory layout (%p, %p), wont work.\n", First, Ours);
    245  1.1     pooka         return 0;
    246  1.1     pooka     }
    247  1.1     pooka 
    248  1.1     pooka     /* Second pass now */
    249  1.1     pooka     base += First->BaseAddressAndTag & RAMBT_BASE;
    250  1.1     pooka     for (Pmt = ThePmt;;Pmt--) {
    251  1.1     pooka         tag = Pmt->Tag;
    252  1.1     pooka         //printf("PMT @%x tag=%x\n",Pmt,tag);
    253  1.1     pooka         switch (tag) {
    254  1.1     pooka         case PMTTAG_END_OF_TABLE:
    255  1.1     pooka             goto DoneSecond;
    256  1.1     pooka         case PMTTAG_SRAM:
    257  1.1     pooka         case PMTTAG_DDRAM:
    258  1.1     pooka         case PMTTAG_FLASH:
    259  1.1     pooka             Ram = (ram_controller_t)(Pmt->TopOfPhysicalAddress << 16);
    260  1.1     pooka             /* Scan the whole segment */
    261  1.1     pooka             for (;;) {
    262  1.1     pooka                 //printf("RAM @%x tag=%x ctl=%x\n", Ram, Ram->BaseAddressAndTag,Ram->Control);
    263  1.1     pooka                 if (tag != (Ram->BaseAddressAndTag & RAMBT_TAG))
    264  1.1     pooka                     break;
    265  1.1     pooka                 /* Leave us alone */
    266  1.1     pooka                 if (Ram == Ours)
    267  1.1     pooka                     goto Next;
    268  1.1     pooka                 /* Leave the first alone too */
    269  1.1     pooka                 if (Ram == First)
    270  1.1     pooka                     goto Next;
    271  1.1     pooka                 /* We do FLASH next round */
    272  1.1     pooka                 if (tag == PMTTAG_FLASH)
    273  1.1     pooka                     goto Next;
    274  1.1     pooka 
    275  1.1     pooka                 addr = Ram->BaseAddressAndTag & RAMBT_BASE;
    276  1.1     pooka                 size = Ram->Control & RAMST_SIZE;
    277  1.1     pooka 
    278  1.1     pooka                 /* Dont make it overlap with us */
    279  1.1     pooka                 if ((moi >= base) && (moi < (base + size)))
    280  1.1     pooka                     base += Ours->Control & RAMST_SIZE;
    281  1.1     pooka 
    282  1.1     pooka                 if (addr != base) {
    283  1.6  dholland                     printf("remapping %x+%zx to %x\n", addr, size, base);
    284  1.1     pooka                     Ram->BaseAddressAndTag = base;
    285  1.1     pooka                 }
    286  1.1     pooka                 base += size;
    287  1.1     pooka 
    288  1.1     pooka             Next:
    289  1.1     pooka                 Ram++;
    290  1.1     pooka                 if (tag == PMTTAG_DDRAM) Ram++; /* yeach */
    291  1.1     pooka             }
    292  1.1     pooka             break;
    293  1.1     pooka         default:
    294  1.1     pooka             break;
    295  1.1     pooka         }
    296  1.1     pooka     }
    297  1.1     pooka  DoneSecond:
    298  1.1     pooka 
    299  1.1     pooka     /* Third pass now: FLASH */
    300  1.1     pooka     for (Pmt = ThePmt;;Pmt--) {
    301  1.1     pooka         tag = Pmt->Tag;
    302  1.1     pooka         //printf("PMT @%x tag=%x\n",Pmt,tag);
    303  1.1     pooka         switch (tag) {
    304  1.1     pooka         case PMTTAG_END_OF_TABLE:
    305  1.1     pooka             goto DoneThird;
    306  1.1     pooka         case PMTTAG_FLASH:
    307  1.1     pooka             Ram = (ram_controller_t)(Pmt->TopOfPhysicalAddress << 16);
    308  1.1     pooka             /* Scan the whole segment */
    309  1.1     pooka             for (;;Ram++) {
    310  1.1     pooka                 //printf("RAM @%x tag=%x ctl=%x\n", Ram, Ram->BaseAddressAndTag,Ram->Control);
    311  1.1     pooka                 if (tag != (Ram->BaseAddressAndTag & RAMBT_TAG))
    312  1.1     pooka                     break;
    313  1.1     pooka                 /* Leave us alone */
    314  1.1     pooka                 if (Ram == Ours)
    315  1.1     pooka                     continue;
    316  1.1     pooka 
    317  1.1     pooka                 addr = Ram->BaseAddressAndTag & RAMBT_BASE;
    318  1.1     pooka                 size = Ram->Control & RAMST_SIZE;
    319  1.1     pooka 
    320  1.1     pooka                 /* No need to move if it does not overlap RAM */
    321  1.1     pooka                 if (addr >= base)
    322  1.1     pooka                     continue;
    323  1.1     pooka 
    324  1.1     pooka                 /* Ahi */
    325  1.1     pooka                 printf("remapping FLASH %x+%x to %x\n", addr, size, base);
    326  1.1     pooka                 Ram->BaseAddressAndTag = base;
    327  1.1     pooka                 base += size;
    328  1.1     pooka             }
    329  1.1     pooka             break;
    330  1.1     pooka         default:
    331  1.1     pooka             break;
    332  1.1     pooka         }
    333  1.1     pooka     }
    334  1.1     pooka DoneThird:
    335  1.1     pooka     return (nfl<<16) | (nsr << 8) | (ndr << 0);
    336  1.1     pooka }
    337  1.1     pooka 
    338  1.1     pooka u_int startjump[2];
    339  1.1     pooka u_int exceptioncode[(0x200-0x080)/4]; /* Change if ExceptionHandlerEnd changes */
    340  1.1     pooka 
    341  1.1     pooka void save_locore(void)
    342  1.1     pooka {
    343  1.1     pooka     memcpy(startjump,start,sizeof startjump);
    344  1.1     pooka     memcpy(exceptioncode,ExceptionHandler,sizeof exceptioncode);
    345  1.1     pooka }
    346  1.1     pooka 
    347  1.1     pooka void restore_locore(void)
    348  1.1     pooka {
    349  1.1     pooka     memcpy(start,startjump,sizeof startjump);
    350  1.1     pooka     memcpy(ExceptionHandler,exceptioncode,sizeof exceptioncode);
    351  1.1     pooka     /* BUGBUG flush icache */
    352  1.1     pooka }
    353  1.1     pooka 
    354  1.1     pooka void call_kernel(uint32_t addr, char *kname, char *kargs, u_int bim, char *bip)
    355  1.1     pooka {
    356  1.1     pooka     int argc = 0;
    357  1.1     pooka     string_t argv[3];
    358  1.1     pooka     int code = PROM_MAGIC;
    359  1.1     pooka     struct callback * cv = &cb;
    360  1.1     pooka 
    361  1.1     pooka     /* Safeguard ourselves */
    362  1.1     pooka     save_locore();
    363  1.1     pooka 
    364  1.1     pooka     if (kargs == NULL) kargs = "";
    365  1.1     pooka     argv[0] = kname;
    366  1.1     pooka     argv[1] = kargs;
    367  1.1     pooka     argv[2] = NULL;
    368  1.1     pooka     argc = 2;
    369  1.1     pooka 
    370  1.1     pooka     TRACE(("Geronimo(%x,%s %s)!\n",addr,kname,kargs));
    371  1.1     pooka     ((void(*)(int,char**,int,struct callback *,u_int,char*))addr)
    372  1.1     pooka            (argc,argv,code,cv,bim,bip);
    373  1.1     pooka }
    374  1.1     pooka 
    375