home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / gnu / gdb-4.14-src.lha / gdb-4.14 / gdb / sparclite / salib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-24  |  6.5 KB  |  369 lines

  1. /* Stand-alone library for SPARClite */
  2.  
  3. #include "sparclite.h"
  4.  
  5. #ifdef SL931
  6. #define SDTR_BASE 0x200
  7. #define SDTR_ASI 1
  8. #define SDTR_SHIFT 0
  9. #else
  10. #define SDTR_BASE 0x10000000
  11. #define SDTR_ASI 4
  12. #define SDTR_SHIFT 16
  13. #endif
  14.  
  15. #define get_uart_status(PORT) \
  16.   ({unsigned long status; \
  17.       read_asi (SDTR_ASI, SDTR_BASE + 0x24 + PORT * 0x10, status); \
  18.     status >> SDTR_SHIFT; })
  19.  
  20. #define xmt_char(PORT, C) write_asi (SDTR_ASI, SDTR_BASE + 0x20 + PORT * 0x10, C << SDTR_SHIFT)
  21.  
  22. #define rcv_char(PORT) \
  23.   ({unsigned long c; \
  24.       read_asi (SDTR_ASI, SDTR_BASE + 0x20 + PORT * 0x10, c); \
  25.     c >> SDTR_SHIFT; })
  26.  
  27. #if 0
  28. void
  29. set_uart (cmd)
  30.      int cmd;
  31. {
  32.   write_asi (SDTR_ASI, SDTR_BASE + 0x24, cmd << SDTR_SHIFT);
  33. }
  34.  
  35. void
  36. set_timer_3 (val)
  37.      int val;
  38. {
  39.   write_asi (SDTR_ASI, SDTR_BASE + 0x78, val << SDTR_SHIFT);
  40. }
  41. #endif
  42.  
  43. /* This cache code is known to work on both the 930 & 932 processors.  It just
  44.    cheats and clears the all of the address space that could contain tags, as
  45.    opposed to striding the tags at 8 or 16 word intervals, or using the cache
  46.    flush registers, which don't exist on all processors.  */
  47.  
  48. void
  49. cache_off ()
  50. {
  51.   write_asi (1, 0, 0);
  52. }
  53.  
  54. void
  55. cache_on ()
  56. {
  57.   unsigned long addr;
  58.  
  59.   cache_off ();            /* Make sure the cache is off */
  60.  
  61.   /* Reset all of the cache line valid bits */
  62.  
  63.   for (addr = 0; addr < 0x1000; addr += 8)
  64.     {
  65.       write_asi (0xc, addr, 0);    /* Clear bank 1, icache */
  66.       write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
  67.  
  68.       write_asi (0xe, addr, 0);    /* Clear bank 1, dcache */
  69.       write_asi (0xe, addr + 0x80000000, 0); /* Clear bank 2, dcache */
  70.     }
  71.  
  72.   /* turn on the cache */
  73.  
  74.   write_asi (1, 0, 0x35);    /* Write buf ena, prefetch buf ena, data
  75.                    & inst caches enab */
  76. }
  77.  
  78. /* Flush the instruction cache.  We need to do this for the debugger stub so
  79.    that breakpoints, et. al. become visible to the instruction stream after
  80.    storing them in memory.
  81.  */
  82.  
  83. void
  84. flush_i_cache ()
  85. {
  86.   int cache_reg;
  87.   unsigned long addr;
  88.  
  89.   read_asi (1, 0, cache_reg);    /* Read cache/bus interface reg */
  90.  
  91.   if (!(cache_reg & 1))
  92.     return;            /* Just return if cache is already off */
  93.  
  94.   for (addr = 0; addr < 0x1000; addr += 8)
  95.     {
  96.       write_asi (0xc, addr, 0);    /* Clear bank 1, icache */
  97.       write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
  98.     }
  99. }
  100.  
  101. asm("
  102.     .text
  103.     .align 4
  104.  
  105. ! Register window overflow handler.  Come here when save would move us
  106. ! into the invalid window.  This routine runs with traps disabled, and
  107. ! must be careful not to touch the condition codes, as PSR is never
  108. ! restored.
  109. !
  110. ! We are called with %l0 = wim, %l1 = pc, %l2 = npc
  111.  
  112.     .globl win_ovf
  113. win_ovf:
  114.     mov    %g1, %l3        ! Save g1, we use it to hold the wim
  115.     srl    %l0, 1, %g1        ! Rotate wim right
  116.     sll    %l0, 8-1, %l0
  117.     or    %l0, %g1, %g1
  118.  
  119.     save    %g0, %g0, %g0        ! Slip into next window
  120.     mov    %g1, %wim        ! Install the new wim
  121.  
  122.     std    %l0, [%sp + 0 * 4]    ! save L & I registers
  123.     std    %l2, [%sp + 2 * 4]
  124.     std    %l4, [%sp + 4 * 4]
  125.     std    %l6, [%sp + 6 * 4]
  126.  
  127.     std    %i0, [%sp + 8 * 4]
  128.     std    %i2, [%sp + 10 * 4]
  129.     std    %i4, [%sp + 12 * 4]
  130.     std    %i6, [%sp + 14 * 4]
  131.  
  132.     restore                ! Go back to trap window.
  133.     mov    %l3, %g1        ! Restore %g1
  134.  
  135.     jmpl    %l1,  %g0
  136.     rett    %l2
  137.  
  138. ! Register window underflow handler.  Come here when restore would move us
  139. ! into the invalid window.  This routine runs with traps disabled, and
  140. ! must be careful not to touch the condition codes, as PSR is never
  141. ! restored.
  142. !
  143. ! We are called with %l0 = wim, %l1 = pc, %l2 = npc
  144.  
  145.     .globl win_unf
  146. win_unf:
  147.     sll    %l0, 1, %l3        ! Rotate wim left
  148.     srl    %l0, 8-1, %l0
  149.     or    %l0, %l3, %l0
  150.  
  151.     mov    %l0, %wim        ! Install the new wim
  152.  
  153.     restore                ! User's window
  154.     restore                ! His caller's window
  155.  
  156.     ldd    [%sp + 0 * 4], %l0    ! restore L & I registers
  157.     ldd    [%sp + 2 * 4], %l2
  158.     ldd    [%sp + 4 * 4], %l4
  159.     ldd    [%sp + 6 * 4], %l6
  160.  
  161.     ldd    [%sp + 8 * 4], %i0
  162.     ldd    [%sp + 10 * 4], %i2
  163.     ldd    [%sp + 12 * 4], %i4
  164.     ldd    [%sp + 14 * 4], %i6
  165.  
  166.     save    %g0, %g0, %g0        ! Back to trap window
  167.     save    %g0, %g0, %g0
  168.  
  169.     jmpl    %l1,  %g0
  170.     rett    %l2
  171.  
  172. ! Read the TBR.
  173.  
  174.     .globl _rdtbr
  175. _rdtbr:
  176.     retl
  177.     mov    %tbr, %o0
  178.  
  179. ");
  180.  
  181. extern unsigned long rdtbr();
  182.  
  183. void
  184. die(val)
  185.      int val;
  186. {
  187.   static unsigned char *leds = (unsigned char *)0x02000003;
  188.  
  189.   *leds = val;
  190.  
  191.   while (1) ;
  192. }
  193.  
  194. void
  195. __main()
  196. {
  197.   int x;
  198.  
  199. #if 0
  200.   set_uart_stuff(0x4e);
  201.   rdtbr();
  202.   rdtbr();
  203.   rdtbr();
  204.   rdtbr();
  205.   rdtbr();
  206.   set_uart_stuff(0x35);
  207. #endif
  208. };
  209.  
  210. /* Each entry in the trap vector occupies four words. */
  211.  
  212. struct trap_entry
  213. {
  214.   unsigned sethi_filler:10;
  215.   unsigned sethi_imm22:22;
  216.   unsigned jmpl_filler:19;
  217.   unsigned jmpl_simm13:13;
  218.   unsigned long filler[2];
  219. };
  220.  
  221. extern struct trap_entry fltr_proto;
  222. asm ("
  223.     .data
  224.     .globl _fltr_proto
  225.     .align 4
  226. _fltr_proto:            ! First level trap routine prototype
  227.     sethi 0, %l0
  228.     jmpl 0+%l0, %g0
  229.     nop
  230.     nop
  231.  
  232.     .text
  233.     .align 4
  234. ");
  235.  
  236. void
  237. exceptionHandler(tt, routine)
  238.      int tt;
  239.      unsigned long routine;
  240. {
  241.   struct trap_entry *tb;    /* Trap vector base address */
  242.  
  243.   tb = (struct trap_entry *)(rdtbr() & ~0xfff);
  244.  
  245.   tb[tt] = fltr_proto;
  246.  
  247.   tb[tt].sethi_imm22 = routine >> 10;
  248.   tb[tt].jmpl_simm13 = routine & 0x3ff;
  249. }
  250.  
  251. void
  252. update_leds()
  253. {
  254.   static unsigned char *leds = (unsigned char *)0x02000003;
  255.   static unsigned char curled = 1;
  256.   static unsigned char dir = 0;
  257.  
  258.   *leds = ~curled;
  259.  
  260.   if (dir)
  261.     curled <<= 1;
  262.   else
  263.     curled >>= 1;
  264.  
  265.   if (curled == 0)
  266.     {
  267.       if (dir)
  268.     curled = 0x80;
  269.       else
  270.     curled = 1;
  271.       dir = ~dir;
  272.     }
  273. }
  274.  
  275.  /* 1/5th of a second? */
  276.  
  277. #define LEDTIME (20000000 / 500)
  278.  
  279. int
  280. getDebugChar()
  281. {
  282.   unsigned long countdown = LEDTIME;
  283.  
  284.   update_leds();
  285.  
  286.   while (1)
  287.     {
  288.       if ((get_uart_status(0) & 2) != 0) break;
  289.  
  290.       if (countdown-- == 0)
  291.     {
  292.       countdown = LEDTIME;
  293.       update_leds();
  294.     }
  295.     }
  296.  
  297.   return rcv_char(0);
  298. }
  299.  
  300. /* Output one character to the serial port */
  301.  
  302. void
  303. putDebugChar(c)
  304.      int c;
  305. {
  306.   update_leds();
  307.  
  308.   while ((get_uart_status(0) & 1) == 0) ;
  309.  
  310.   xmt_char(0, c);
  311. }
  312.  
  313. int
  314. write(fd, data, length)
  315.      int fd;
  316.      unsigned char *data;
  317.      int length;
  318. {
  319.   int olength = length;
  320.  
  321.   while (length--)
  322.     putDebugChar(*data++);
  323.  
  324.   return olength;
  325. }
  326.  
  327. int
  328. read(fd, data, length)
  329.      int fd;
  330.      unsigned char *data;
  331.      int length;
  332. {
  333.   int olength = length;
  334.   int c;
  335.  
  336.   while (length--)
  337.     *data++ = getDebugChar();
  338.  
  339.   return olength;
  340. }
  341.  
  342. /* Set the baud rate for the serial port, returns 0 for success,
  343.    -1 otherwise */
  344.  
  345. #if 0
  346. int
  347. set_baud_rate(baudrate)
  348.      int baudrate;
  349. {
  350.   /* Convert baud rate to uart clock divider */
  351.   switch (baudrate)
  352.     {
  353.     case 38400:
  354.       baudrate = 16;
  355.       break;
  356.     case 19200:
  357.       baudrate = 33;
  358.       break;
  359.     case 9600:
  360.       baudrate = 65;
  361.       break;
  362.     default:
  363.       return -1;
  364.     }
  365.  
  366.   set_timer_3(baudrate);    /* Set it */
  367. }
  368. #endif
  369.