home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 575.lha / Personal040DevelopSoft / fastrom040.c < prev    next >
C/C++ Source or Header  |  1991-11-05  |  7KB  |  251 lines

  1. /*
  2.     FastROM040 V1.0a for the Progressive Peripipherals & Software 040/A3000
  3.         by Greg Tibbs; some code from  SetCPU V1.4 by Dave Haynie
  4.  
  5.     MAIN PROGRAM
  6.  
  7.         Assumptions: The PPS 040 for the A3000 only works under 2.0+, so 
  8.                      assumptions that exec knows about an 040, that ROMsize
  9.                      is 512K. The PPS 040 has no onboard memory, so the
  10.                      area mapped from 0x0100000 on to the base of the A3000
  11.                      motherboard Ram is made invalid in the Address translation
  12.                      cache and accesses there will yield an address error
  13.                      exception. Zorro III memory area is made data &
  14.                      instruciton cachable, with ZorroII I/o space not
  15.                      cachable at all (040 limitation in that there is no
  16.                      ddistinction in the ATC between data accesses and 
  17.                      instruction accesses. The only way around this is
  18.                       with the mTTX registers which will be used primarily
  19.                      in fast ram. 
  20.     
  21. */
  22.  
  23. #define PROGRAM_VERSION    "V1.0a"
  24.  
  25. #include <exec/types.h>
  26. #include <exec/execbase.h>
  27. #include <exec/nodes.h>
  28. #include <exec/interrupts.h>
  29. #include <stdio.h>
  30.  
  31. /* ====================================================================== */
  32.  
  33. /* Define all bit components used for manipulation of the Cache Control
  34.    Register. */
  35.  
  36. #define CACR_INST    (1L<<15)
  37. #define CACR_DATA    (1L<<31)
  38. #define CACR_ENB    (CACR_INST | CACR_DATA)
  39.  
  40. #define ROUND        0x00002000L
  41. #define ROMBASE        0x00F80000L
  42. #define ROMSIZE        0x00080000L
  43. #define TABSIZE        (128L * sizeof(ULONG))
  44. #define LEV3TABSIZE     0x2000L
  45.  
  46.  
  47. /* ====================================================================== */
  48.  
  49. /* Define important bits used in various MMU registers. */
  50. /* Here are the TC definitions.  The TC register is 32 bits long. */
  51.  
  52. #define    TC_ENB        ((1L<<15)+(1L<<14)+(1L<<31)+(1L<<30)) /* Enable the MMU with 8K pages*/
  53.  
  54. /* Here are the page descriptor definitions, for short desctriptors only,
  55.    since that's all I'm using at this point. */
  56.    
  57. /* ====================================================================== */
  58.  
  59. /* Some external declarations. */
  60.  
  61. void SetCACR(), DumpCache(), SetCRP(), SetTC();
  62. void SetITT0(), SetITT1(), SetDTT0(), SetDTT1();
  63. ULONG GetCACR(), GetTC(), GetCPUType(), GetCRP();
  64. ULONG GetDTT0(), GetDTT1(), GetITT0(), GetITT1();
  65.  
  66. /* ====================================================================== */
  67.  
  68. /* This replaces the Lattice "stricmp()" function, plus it's a better form
  69.    for my needs here. */
  70.    
  71. static BOOL striequ(s1,s2)
  72. char *s1,*s2;
  73. {
  74.    BOOL aok;
  75.    
  76.    while (*s1 && *s2 && (aok = (*s1++ & 0xdf) == (*s2++ & 0xdf)));
  77.    return (BOOL) (!*s1 && aok);
  78. }
  79. /* ====================================================================== */
  80.  
  81.  
  82. /* Page tables and other MMU stuff must be on a page sized boundary, and
  83.    that boundary must be a power of two.  This routine allocates such an
  84.    aligned block of memory. */
  85.  
  86. void *AllocAligned(size,bound)
  87. ULONG size;
  88. ULONG bound;
  89. {
  90.    void *mem, *aligned;
  91.    
  92.    if (!(mem = (void *)AllocMem(size+bound,0L))) return NULL;   
  93.    Forbid();
  94.    aligned = (void *)(((ULONG)mem + bound - 1) & ~(bound - 1));
  95.    FreeMem(mem,size+bound);
  96.    mem = (void *)AllocAbs(size,aligned);
  97.    Permit();
  98.    return mem;
  99. }
  100.  
  101.  
  102. int main(argc,argv)
  103. int argc;
  104. char *argv[];
  105. {
  106.    ULONG i, cpu, myCRP, myTC, cacr, ROMADDR, *MMUTable;
  107.    ULONG dtt0,*MMUTable2,*MMUTable3, *ROM32;
  108.    ULONG fdtt0, fdtt1,fitt0,fitt1,cache;
  109.  
  110.    /* If they're just asking for help */
  111.  
  112.    if (argc >= 2 && argv[1][0] == '?') {
  113.       printf("\n\2337mFASTROM040 %s For PPS 040/A3000\2330m [CACHEZ2]\n"
  114.             ,PROGRAM_VERSION);
  115.       exit(0L);
  116.    }
  117.  
  118.    cache = 0L;
  119.    if (argc >=2 && striequ(argv[1],"CACHEZ2")) 
  120.    {
  121.      cache=1L;
  122.      printf("Zorro II area will be cached!\n");
  123.    }
  124.  
  125.   /* Let's find out what we have, and perform the ROM translation */
  126.  
  127.    if ((cpu=GetCPUType())==68040) 
  128.    {
  129.       printf("68040 CPU found.\n");
  130.    }
  131.    else 
  132.    {
  133.       printf("68040 Not Present!!!\n");
  134.       exit(5L);
  135.    }
  136.  
  137.    myTC=GetTC();
  138.    if (myTC & TC_ENB) {
  139.    printf("MMU in operation! FastROM not performed.\n");
  140.    exit(5L);
  141.    }
  142.  
  143. /* This routine creates the Fast ROM.  If the memory can't be allocated,
  144.    it returns FALSE, otherwise, TRUE. */
  145.  
  146.  
  147.   /* First off, get the memory for the 32 bit ROM and the MMU table. */
  148.  
  149.    ROM32     = AllocAligned(ROMSIZE,ROUND);
  150.    MMUTable  = AllocAligned(TABSIZE,ROUND);
  151.    MMUTable2 = AllocAligned(TABSIZE,ROUND);
  152.    MMUTable3 = AllocAligned(LEV3TABSIZE,ROUND);
  153.  
  154.  
  155.    if (!ROM32 || !MMUTable || !MMUTable2 || !MMUTable3) {
  156.       if (MMUTable)   FreeMem(MMUTable,TABSIZE);
  157.       if (MMUTable2)  FreeMem(MMUTable2,TABSIZE);
  158.       if (MMUTable3)  FreeMem(MMUTable3,LEV3TABSIZE);
  159.       if (ROM32)      FreeMem(ROM32,ROMSIZE);
  160.       printf("Memory Failure in FastROM allocation!\n");
  161.  
  162.       exit(5L);
  163.    }
  164.  
  165.   ROMADDR=(ULONG)ROM32;
  166.  
  167.   /* Here I set up the ROM, as quickly as possible! */
  168.  
  169.    CopyMemQuick(ROMBASE,ROM32,ROMSIZE);
  170.      
  171.  
  172. /* MMUTable is the root pointer table for the ATC. mTTx covers 3/4 of all RAM
  173.    so all but the lowest 32 Meg is declared invalid to save table space. The 
  174.    mTTx registers overrides this table, so most A3000 ram areas are OK except
  175.    some Zorro III areas, which are spotty. 
  176.  
  177.    MMUTable2 is the 2nd level table for the lower 32 Meg of address space.
  178.    The upper 16 Meg will be declared invalid to save space. The lower
  179.    16 meg is addressed via MMUTable3 which actually contains 64 tables of
  180.    thirty-two 8K page descriptors. */
  181.  
  182.    /* Set up 1st Level Table */
  183.  
  184.    for (i = 1; i < 128; i++) *(MMUTable+i) = 0L; //Invalid Pages (> 32Meg)
  185.    MMUTable[0] = (((ULONG)MMUTable2 & ~0x1ffL) | 0x3L); //Point to Level 2 Table
  186.  
  187.    /* Set up 2nd Level Table */
  188.  
  189.    for (i=64; i<128;i++) *(MMUTable2+i)=0L;  //Invalid Pages (>16Meg, < 32Meg)
  190.    for (i=0;i<64;i++) *(MMUTable2+i)=(((ULONG)&MMUTable3[i*32]&~0x7fL)|0x3L);
  191.  
  192.    /* Set up 3rd level Tables */
  193.  
  194.    for (i=0;i<1984;i++) *(MMUTable3+i) = (((8192*i) & ~0x1fffL) | 0x441L);
  195.    for (i=0;i<64;i++) *(MMUTable3+i+1984)=(((ROMADDR+(8192*i))&~0x1fffL)|0x405L);
  196.    if(cache>0)  for(i=256;i<1280;i++) *(MMUTable3+i)+=0x3CL; // Turn on Z2 caching
  197.       
  198.   /* Now I have to set up the MMU.  The User Root Pointer tells the MMU about 
  199.      the table I've set up, and the Translation Control register will turn 
  200.      the thing on.  */
  201.  
  202. /* itt0 = 0L;
  203.    itt1 = 0xffc000L;*/
  204.    dtt0 = 0xc040L;
  205. /* dtt1 = 0xffc020L;  Default Progressive Translation register values */
  206.  
  207.    fdtt0=0x04fbc020L; // Set up Data Translation Registers
  208.    fdtt1=0x08f7c020L;
  209.    fitt0=0x04fbc000L; // Set up Instruction Translation Registers
  210.    fitt1=0x08f7c000L;
  211.  
  212.    Forbid();
  213.    Disable();
  214.  
  215.    SetDTT1(0L);
  216.    SetDTT0(dtt0);
  217.    SetITT1(0L);
  218.    SetITT0(0L);
  219.  
  220.    SetTC(0L);    //   Disable Address Translations
  221.    SetCACR(0L);  //   Turn I & D Caches off
  222.    DumpCache();  //   Flush Data, Instruction and ATC
  223.  
  224.  
  225. /* Note that mTTx are overriding all ATC entries that I set up */
  226.  
  227.    myCRP = (ULONG)MMUTable & ~0x1ffL; // Set URP & SRP
  228.    SetCRP(myCRP);
  229.  
  230.    SetDTT1(fdtt1);// Send new mTTx registers which match ATC Tables
  231.    SetDTT0(fdtt0);
  232.    SetITT1(fitt1);
  233.    SetITT0(fitt0);
  234.  
  235.    myTC = TC_ENB;
  236.    SetTC(myTC);   // Enable Translation via tables
  237.  
  238.    Enable();
  239.    Permit();
  240.  
  241.    DumpCache(); 
  242.    cacr = CACR_ENB;
  243.    SetCACR(cacr); // Turn on Data and Instruction Caches
  244.  
  245.    printf("Fastrom enabled.\n ");
  246.  
  247.  
  248.    exit(0L);
  249. }
  250.  
  251.