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/i386/i386/elan-mmcr.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 /*
    2  * ----------------------------------------------------------------------------
    3  * "THE BEER-WARE LICENSE" (Revision 42):
    4  * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
    5  * can do whatever you want with this stuff. If we meet some day, and you think
    6  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
    7  * ----------------------------------------------------------------------------
    8  *
    9  * $FreeBSD$
   10  * The AMD Elan sc520 is a system-on-chip gadget which is used in embedded
   11  * kind of things, see www.soekris.com for instance, and it has a few quirks
   12  * we need to deal with.
   13  * Unfortunately we cannot identify the gadget by CPUID output because it
   14  * depends on strapping options and only the stepping field may be useful
   15  * and those are undocumented from AMDs side.
   16  *
   17  * So instead we recognize the on-chip host-PCI bridge and call back from
   18  * sys/i386/pci/pci_bus.c to here if we find it.
   19  */
   20 
   21 #include <sys/param.h>
   22 #include <sys/systm.h>
   23 #include <sys/kernel.h>
   24 #include <sys/conf.h>
   25 #include <sys/proc.h>
   26 #include <sys/sysctl.h>
   27 #include <sys/time.h>
   28 
   29 #include <machine/md_var.h>
   30 
   31 #include <vm/vm.h>
   32 #include <vm/pmap.h>
   33 
   34 uint16_t *elan_mmcr;
   35 
   36 
   37 static unsigned
   38 elan_get_timecount(struct timecounter *tc)
   39 {
   40         return (elan_mmcr[0xc84 / 2]);
   41 }
   42 
   43 static struct timecounter elan_timecounter = {
   44         elan_get_timecount,
   45         0,
   46         0xffff,
   47         33333333 / 4,
   48         "ELAN"
   49 };
   50 
   51 void
   52 init_AMD_Elan_sc520(void)
   53 {
   54         u_int new;
   55         int i;
   56 
   57         if (bootverbose)
   58                 printf("Doing h0h0magic for AMD Elan sc520\n");
   59         elan_mmcr = pmap_mapdev(0xfffef000, 0x1000);
   60 
   61         /*-
   62          * The i8254 is driven with a nonstandard frequency which is
   63          * derived thusly:
   64          *   f = 32768 * 45 * 25 / 31 = 1189161.29...
   65          * We use the sysctl to get the timecounter etc into whack.
   66          */
   67         
   68         new = 1189161;
   69         i = kernel_sysctlbyname(curproc, "machdep.i8254_freq", 
   70             NULL, 0, 
   71             &new, sizeof new, 
   72             NULL);
   73         if (bootverbose)
   74                 printf("sysctl machdep.i8254_freq=%d returns %d\n", new, i);
   75 
   76         /* Start GP timer #2 and use it as timecounter, hz permitting */
   77         elan_mmcr[0xc82 / 2] = 0xc001;
   78         init_timecounter(&elan_timecounter);
   79 }
   80 
   81 
   82 /*
   83  * Device driver initialization stuff
   84  */
   85 
   86 static d_open_t elan_open;
   87 static d_close_t elan_close;
   88 static d_ioctl_t elan_ioctl;
   89 static d_mmap_t elan_mmap;
   90 
   91 #define CDEV_MAJOR 100                  /* Share with xrpu */
   92 static struct cdevsw elan_cdevsw = {
   93         /* open */      elan_open,
   94         /* close */     elan_close,
   95         /* read */      noread,
   96         /* write */     nowrite,
   97         /* ioctl */     elan_ioctl,
   98         /* poll */      nopoll,
   99         /* mmap */      elan_mmap,
  100         /* strategy */  nostrategy,
  101         /* name */      "elan",
  102         /* maj */       CDEV_MAJOR,
  103         /* dump */      nodump,
  104         /* psize */     nopsize,
  105         /* flags */     0,
  106 };
  107 
  108 static int
  109 elan_open(dev_t dev, int flag, int mode, struct proc *p)
  110 {
  111         return (0);
  112 }
  113 
  114 static int
  115 elan_close(dev_t dev, int flag, int mode, struct proc *p)
  116 { 
  117         return (0);
  118 }
  119 
  120 static int
  121 elan_mmap(dev_t dev, vm_offset_t offset, int nprot)
  122 {
  123         if (offset >= 0x1000) 
  124                 return (-1);
  125         return (i386_btop(0xfffef000));
  126 }
  127 
  128 static int
  129 elan_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
  130 {
  131         return(ENOENT);
  132 }
  133 
  134 static void
  135 elan_drvinit(void)
  136 {
  137 
  138         if (elan_mmcr == NULL)
  139                 return;
  140         printf("Elan-mmcr driver: MMCR at %p\n", elan_mmcr);
  141         make_dev(&elan_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "elan-mmcr");
  142         return;
  143 }
  144 
  145 SYSINIT(elan, SI_SUB_PSEUDO, SI_ORDER_MIDDLE+CDEV_MAJOR,elan_drvinit,NULL);

Cache object: 43387a48002a94df0e6c289cb008ff1c


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