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/uartsaturn.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 "../port/error.h"
    8 #include "msaturn.h"
    9 
   10 enum{
   11         UartAoffs = Saturn + 0x0a00,
   12         UartBoffs = Saturn + 0x0b00,
   13         Nuart = 2,
   14 
   15         Baudfreq = 14745600 / 16,
   16         Lcr_div = RBIT(1, uchar),
   17         Lcr_peven = RBIT(3, uchar),
   18         Lcr_pen = RBIT(4, uchar),
   19         Lcr_stop = RBIT(5, uchar),
   20         Lcr_wrdlenmask = RBIT(6, uchar) | RBIT(7, uchar),
   21         Lcr_wrdlenshift = 0,
   22         Lsr_tbre = RBIT(2, uchar),      
   23         Fcr_txreset = RBIT(5, uchar),
   24         Fcr_rxreset = RBIT(6, uchar),
   25         Iir_txempty = RBIT(5, uchar),
   26         Iir_rxfull = RBIT(6, uchar),
   27         Iir_rxerr = RBIT(7, uchar),
   28         Ier_rxerr = RBIT(5, uchar),
   29         Ier_txempty = RBIT(6, uchar),
   30         Ier_rxfull = RBIT(7, uchar),
   31         Lsr_rxavail = RBIT(7, uchar),
   32         Txsize = 16,
   33         Rxsize = 16,
   34 };
   35 
   36 typedef struct Saturnuart Saturnuart;
   37 struct Saturnuart {
   38         uchar   rxb;
   39 #define txb     rxb
   40 #define dll     rxb
   41         uchar   ier;                    // Interrupt enable, divisor latch
   42 #define dlm     ier
   43         uchar   iir;                    // Interrupt identification, fifo control
   44 #define fcr     iir     
   45         uchar   lcr;                    // Line control register
   46         uchar   f1;             
   47         uchar   lsr;                    // Line status register
   48         ushort  f2;
   49 };
   50 
   51 typedef struct UartData UartData;
   52 struct UartData {
   53         int                     suno;   /* saturn uart number: 0 or 1 */
   54         Saturnuart      *su;
   55         char                    *rxbuf;
   56         char                    *txbuf;
   57         int                     initialized;
   58         int                     enabled;
   59 } uartdata[Nuart];
   60 
   61 extern PhysUart saturnphysuart;
   62 
   63 Uart suart[Nuart] = {
   64         {
   65                 .name = "SaturnUart1",
   66                 .baud = 19200,
   67                 .bits = 8,
   68                 .stop = 1,
   69                 .parity = 'n',
   70                 .phys = &saturnphysuart,
   71                 .special = 0,
   72         },
   73         {
   74                 .name = "SaturnUart2",
   75                 .baud = 115200,
   76                 .bits = 8,
   77                 .stop = 1,
   78                 .parity = 'n',
   79                 .phys = &saturnphysuart,
   80                 .special = 0,
   81         },
   82 };
   83 
   84 static void suinterrupt(Ureg*, void*);
   85 
   86 static Uart*
   87 supnp(void)
   88 {
   89         int i;
   90 
   91         for (i = 0; i < nelem(suart)-1; i++)
   92                 suart[i].next = &suart[i + 1];
   93         suart[nelem(suart)-1].next=nil;
   94         return suart;
   95 }
   96 
   97 static void
   98 suinit(Uart*uart)
   99 {
  100         UartData *ud;
  101         Saturnuart *su;
  102 
  103         ud = uart->regs;
  104         su = ud->su;
  105         su->fcr=Fcr_txreset|Fcr_rxreset;
  106         ud->initialized=1;
  107 }
  108 
  109 static void
  110 suenable(Uart*uart, int ie)
  111 {
  112         Saturnuart *su;
  113         UartData *ud;
  114         int nr;
  115 
  116         nr = uart - suart;
  117         if (nr < 0 || nr > Nuart)
  118                 panic("No uart %d", nr);
  119         ud = uartdata + nr;
  120         ud->suno = nr;
  121         su=ud->su = (Saturnuart*)((nr == 0)? UartAoffs: UartBoffs);
  122         uart->regs = ud;
  123 
  124         if(ud->initialized==0)
  125                 suinit(uart);
  126 
  127         if(!ud->enabled && ie){
  128                 intrenable(Vecuart0+nr , suinterrupt, uart, uart->name);
  129                 su->ier=Ier_txempty|Ier_rxfull;
  130                 ud->enabled=1;
  131         }
  132 }
  133 
  134 
  135 static long
  136 sustatus(Uart* uart, void* buf, long n, long offset)
  137 {
  138         Saturnuart *su;
  139         char p[128];
  140 
  141         su = ((UartData*)uart->regs)->su;
  142         snprint(p, sizeof p, "b%d c%d e%d l%d m0 p%c s%d i1\n"
  143                 "dev(%d) type(%d) framing(%d) overruns(%d)\n",
  144 
  145                 uart->baud,
  146                 uart->hup_dcd, 
  147                 uart->hup_dsr,
  148                 Txsize,
  149                 (su->lcr & Lcr_pen)? ((su->lcr & Lcr_peven) ? 'e': 'o'): 'n',
  150                 (su->lcr & Lcr_stop)? 2: 1,
  151 
  152                 uart->dev,
  153                 uart->type,
  154                 uart->ferr,
  155                 uart->oerr);
  156         n = readstr(offset, buf, n, p);
  157         free(p);
  158 
  159         return n;
  160 }
  161 
  162 static void
  163 sufifo(Uart*, int)
  164 {}
  165 
  166 static void
  167 sudtr(Uart*, int)
  168 {}
  169 
  170 static void
  171 surts(Uart*, int)
  172 {}
  173 
  174 static void
  175 sumodemctl(Uart*, int)
  176 {}
  177 
  178 static int
  179 suparity(Uart*uart, int parity)
  180 {
  181         int lcr;
  182         Saturnuart *su;
  183 
  184         su = ((UartData*)uart->regs)->su;
  185 
  186         lcr = su->lcr & ~(Lcr_pen|Lcr_peven);
  187 
  188         switch(parity){
  189         case 'e':
  190                 lcr |= (Lcr_pen|Lcr_peven);
  191                 break;
  192         case 'o':
  193                 lcr |= Lcr_pen;
  194                 break;
  195         case 'n':
  196         default:
  197                 break;
  198         }
  199 
  200         su->lcr = lcr;
  201         uart->parity = parity;
  202 
  203         return 0;
  204 }
  205 
  206 static int
  207 sustop(Uart* uart, int stop)
  208 {
  209         int lcr;
  210         Saturnuart *su;
  211 
  212         su = ((UartData*)uart->regs)->su;
  213         lcr = su->lcr & ~Lcr_stop;
  214 
  215         switch(stop){
  216         case 1:
  217                 break;
  218         case 2:
  219                 lcr |= Lcr_stop;
  220                 break;
  221         default:
  222                 return -1;
  223         }
  224 
  225         /* Set new value and reenable if device was previously enabled */
  226         su->lcr = lcr;
  227         uart->stop = stop;
  228 
  229         return 0;
  230 }
  231 
  232 static int
  233 subits(Uart*uart, int n)
  234 {       
  235         Saturnuart *su;
  236         uchar lcr;
  237 
  238         su = ((UartData*)uart->regs)->su;
  239         if(n<5||n>8)
  240                 return -1;
  241 
  242         lcr = su->lcr & ~Lcr_wrdlenmask;
  243         lcr |= (n-5) << Lcr_wrdlenshift;
  244         su->lcr = lcr;
  245         return 0;
  246 }
  247 
  248 static int
  249 subaud(Uart* uart, int baud)
  250 {
  251         ushort v;
  252         Saturnuart *su;
  253 
  254         if (uart->enabled){
  255                 su = ((UartData*)uart->regs)->su;
  256         
  257                 if(baud <= 0)
  258                         return -1;
  259 
  260                 v = Baudfreq / baud;
  261                 su->lcr |= Lcr_div;
  262                 su->dll = v;
  263                 su->dlm = v >> 8;
  264                 su->lcr &= ~Lcr_div;
  265         }
  266         uart->baud = baud;
  267 
  268         return 0;
  269 }
  270 
  271 static void
  272 subreak(Uart*, int)
  273 {}
  274 
  275 static void
  276 sukick(Uart *uart)
  277 {
  278         Saturnuart *su;
  279         int i;
  280 
  281         if(uart->blocked)
  282                 return;
  283 
  284         su = ((UartData*)uart->regs)->su;
  285         if((su->iir & Iir_txempty) == 0)
  286                 return;
  287 
  288         for(i = 0; i < Txsize; i++){
  289                 if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
  290                         break;
  291                 su->txb = *(uart->op++);
  292                 su->ier |= Ier_txempty;
  293                 break;
  294         }
  295 }
  296 
  297 static void
  298 suputc(Uart *uart, int c)
  299 {
  300         Saturnuart *su;
  301 
  302         su = ((UartData*)uart->regs)->su;
  303         while((su->lsr&Lsr_tbre) == 0)
  304                 ;
  305 
  306         su->txb=c;
  307         while((su->lsr&Lsr_tbre) == 0)
  308                         ;
  309 }
  310 
  311 static int
  312 getchars(Uart *uart, uchar *cbuf)
  313 {
  314         int nc;
  315         UartData *ud;
  316         Saturnuart *su;
  317 
  318         ud = uart->regs;
  319         su = ud->su;
  320 
  321         while((su->lsr&Lsr_rxavail) == 0)
  322                 ;
  323 
  324         *cbuf++ = su->rxb;
  325         nc = 1;
  326         while(su->lsr&Lsr_rxavail){
  327                 *cbuf++ = su->rxb;
  328                 nc++;
  329         }
  330         return nc;
  331 }
  332 
  333 static int
  334 sugetc(Uart *uart)
  335 {
  336         static uchar buf[128], *p;
  337         static int cnt;
  338         char    c;
  339 
  340         if (cnt <= 0) {
  341                 cnt = getchars(uart, buf);
  342                 p = buf;
  343         }
  344         c = *p++;
  345         cnt--;
  346         return c;
  347 }
  348 
  349 static void
  350 suinterrupt(Ureg*, void*u)
  351 {
  352         Saturnuart *su;
  353         Uart *uart;
  354         uchar iir;
  355 
  356         uart = u;
  357         if (uart == nil)
  358                 panic("uart is nil");
  359         su = ((UartData*)uart->regs)->su;
  360         iir = su->iir;
  361         if(iir&Iir_rxfull)
  362                 while(su->lsr&Lsr_rxavail)
  363                         uartrecv(uart, su->rxb);
  364         if(iir & Iir_txempty){
  365                 su->ier&=~Ier_txempty;
  366                 uartkick(uart);
  367         }
  368         if (iir & Iir_rxerr)
  369                 uart->oerr++;
  370         intack();
  371 }
  372 
  373 static void
  374 sudisable(Uart* uart)
  375 {
  376         Saturnuart *su;
  377 
  378         su = ((UartData*)uart->regs)->su;
  379         su->ier&=~(Ier_txempty|Ier_rxfull);
  380 }
  381 
  382 PhysUart saturnphysuart = {
  383         .name           = "su",
  384         .pnp                    = supnp,
  385         .enable         = suenable,
  386         .disable                = sudisable,
  387         .kick                   = sukick,
  388         .dobreak                = subreak,
  389         .baud           = subaud,
  390         .bits                   = subits,
  391         .stop                   = sustop,
  392         .parity         = suparity,
  393         .modemctl       = sumodemctl,
  394         .rts                    = surts,
  395         .dtr                    = sudtr,
  396         .status         = sustatus,
  397         .fifo                   = sufifo,
  398         .getc                   = sugetc,
  399         .putc                   = suputc,
  400 };
  401 
  402 void
  403 console(void)
  404 {
  405         Uart *uart;
  406         int n;
  407         char *cmd, *p;
  408 
  409         if((p = getconf("console")) == nil)
  410                 return;
  411         n = strtoul(p, &cmd, 0);
  412         if(p == cmd)
  413                 return;
  414         if(n < 0 || n >= nelem(suart))
  415                 return;
  416 
  417         uart = suart + n;
  418 
  419 /*      uartctl(uart, "b115200 l8 pn s1"); */
  420         if(*cmd != '\0')
  421                 uartctl(uart, cmd);
  422         (*uart->phys->enable)(uart, 0);
  423 
  424         consuart = uart;
  425         uart->console = 1;
  426 } 
  427 
  428 Saturnuart*uart = (Saturnuart*)UartAoffs;
  429 
  430 void
  431 dbgputc(int c)
  432 {
  433         while((uart->lsr&Lsr_tbre) == 0)
  434                 ;
  435 
  436         uart->txb=c;
  437         while((uart->lsr&Lsr_tbre) == 0)
  438                         ;
  439 }
  440 
  441 void
  442 dbgputs(char*s)
  443 {
  444         while(*s)
  445                 dbgputc(*s++);
  446 }
  447 
  448 void
  449 dbgputx(ulong x)
  450 {
  451         int i;
  452         char c;
  453 
  454         for(i=0; i < sizeof(ulong) * 2; i++){
  455                 c = ((x >> (28 - i * 4))) & 0xf;
  456                 if(c >= 0 && c <= 9)
  457                         c += '';
  458                 else
  459                         c += 'a' - 10;
  460 
  461                 while((uart->lsr&Lsr_tbre) == 0)
  462                         ;
  463 
  464                 uart->txb=c;
  465         }
  466         while((uart->lsr&Lsr_tbre) == 0)
  467                         ;
  468 
  469         uart->txb='\n';
  470         while((uart->lsr&Lsr_tbre) == 0)
  471                         ;
  472 }

Cache object: 1f1d4d50344d68441e356d445c356e69


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