Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:44

0001 /*  versions.c
0002  *
0003  *  Milkymist versioning driver for RTEMS
0004  *
0005  *  The license and distribution terms for this file may be
0006  *  found in the file LICENSE in this distribution or at
0007  *  http://www.rtems.org/license/LICENSE.
0008  *
0009  *  COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
0010  */
0011 
0012 #define RTEMS_STATUS_CHECKS_USE_PRINTK
0013 
0014 #include <stdio.h>
0015 #include <stdlib.h>
0016 #include <string.h>
0017 #include <sys/types.h>
0018 #include <rtems.h>
0019 #include <rtems/status-checks.h>
0020 #include <bsp.h>
0021 #include <rtems/libio.h>
0022 #include "../include/system_conf.h"
0023 #include <bsp/milkymist_versions.h>
0024 
0025 #define SOC_DEVICE_NAME "/dev/soc"
0026 #define PCB_DEVICE_NAME "/dev/pcb"
0027 #define PCBREV_DEVICE_NAME "/dev/pcb_rev"
0028 
0029 rtems_device_driver versions_initialize(
0030   rtems_device_major_number major,
0031   rtems_device_minor_number minor,
0032   void *arg
0033 )
0034 {
0035   rtems_status_code sc;
0036 
0037   sc = rtems_io_register_name(SOC_DEVICE_NAME, major, 0);
0038   RTEMS_CHECK_SC(sc, "create SoC version device");
0039   sc = rtems_io_register_name(PCB_DEVICE_NAME, major, 1);
0040   RTEMS_CHECK_SC(sc, "create PCB type device");
0041   sc = rtems_io_register_name(PCBREV_DEVICE_NAME, major, 2);
0042   RTEMS_CHECK_SC(sc, "create PCB revision device");
0043 
0044   return RTEMS_SUCCESSFUL;
0045 }
0046 
0047 static int get_soc_version(char *buffer)
0048 {
0049   char fmt[13];
0050   char *version;
0051   int len;
0052   unsigned int id;
0053   unsigned int major, minor, subminor, rc;
0054 
0055   id = MM_READ(MM_SYSTEM_ID);
0056     major = (id & 0xf0000000) >> 28;
0057     minor = (id & 0x0f000000) >> 24;
0058     subminor = (id & 0x00f00000) >> 20;
0059     rc = (id & 0x000f0000) >> 16;
0060 
0061   version = fmt;
0062   version += sprintf(version, "%u.%u", major, minor);
0063     if (subminor != 0)
0064         version += sprintf(version, ".%u", subminor);
0065     if (rc != 0)
0066         version += sprintf(version, "RC%u", rc);
0067 
0068   len = version - fmt;
0069   memcpy(buffer, fmt, len);
0070   return len;
0071 }
0072 
0073 static int get_pcb_type(char *buffer)
0074 {
0075   unsigned int id;
0076 
0077   id = MM_READ(MM_SYSTEM_ID);
0078   buffer[0] = (id & 0x0000ff00) >> 8;
0079   buffer[1] = id & 0x000000ff;
0080   return 2;
0081 }
0082 
0083 static int get_pcb_revision(char *buffer)
0084 {
0085   unsigned int v;
0086 
0087   v = MM_READ(MM_GPIO_IN);
0088   v = (v & 0x78) >> 3;
0089   buffer[0] = '0' + v;
0090   return 1;
0091 }
0092 
0093 rtems_device_driver versions_read(
0094   rtems_device_major_number major,
0095   rtems_device_minor_number minor,
0096   void *arg
0097 )
0098 {
0099   rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
0100 
0101   if(rw_args->offset != 0) {
0102     rw_args->bytes_moved = 0;
0103     return RTEMS_SUCCESSFUL;
0104   }
0105 
0106   switch (minor) {
0107     case 0:
0108       if (rw_args->count < 12) {
0109         rw_args->bytes_moved = 0;
0110         return RTEMS_UNSATISFIED;
0111       }
0112       rw_args->bytes_moved = get_soc_version((char *)rw_args->buffer);
0113       return RTEMS_SUCCESSFUL;
0114     case 1:
0115       if (rw_args->count < 2) {
0116         rw_args->bytes_moved = 0;
0117         return RTEMS_UNSATISFIED;
0118       }
0119       rw_args->bytes_moved = get_pcb_type((char *)rw_args->buffer);
0120       return RTEMS_SUCCESSFUL;
0121     case 2:
0122       if (rw_args->count < 1) {
0123         rw_args->bytes_moved = 0;
0124         return RTEMS_UNSATISFIED;
0125       }
0126       rw_args->bytes_moved = get_pcb_revision((char *)rw_args->buffer);
0127       return RTEMS_SUCCESSFUL;
0128   }
0129 
0130   rw_args->bytes_moved = 0;
0131   return RTEMS_UNSATISFIED;
0132 }