[PATCH] bsps/shared/ofw: Implement RTEMS OFW interface

Niteesh G. S. niteesh.gs at gmail.com
Tue Aug 18 17:01:50 UTC 2020


On Tue, Aug 18, 2020 at 8:26 PM Christian Mauderer <oss at c-mauderer.de>
wrote:

> On 18/08/2020 11:25, Niteesh G. S. wrote:
> > How can we make this API FreeBSD compatible? We have to declare
> > defines for the OFW functions
> > Eg. #define OF_finddevice rtems_ofw_find_device
>
> I think that was the plan, wasn't it?
>

Is everyone OK with this? I am going to start working on it. I would like to
get at least one of my patches merge ready before GSoC ends.
My other patches are somewhat dependent on this patch so I want to get
this fixed first.

I also have a few questions now. If we do this change in libBSD and what
about the imported drivers present in RTEMS? They have to define these
translations locally in the driver itself. Or we should move openfirm.h into
RTEMS. Both have their own problems. The first one will create a lot of
redundant code And the second one has the following problems.

1) Where to place openfirm.h in RTEMS?
2)  What about functions like OF_device_from_xref etc?
These functions depend on the libBSD device struct one hack is to forward
declare these in the openfirm.h implemented in RTEMS. Is everyone OK
with this or is there any better solution to this?
3) We also modify the interface is that fine with BSD-4 license?


> >
> > Should I change the openfirm.h in libBSD to this use these defines
> instead
> > of calling the functions in openfirm.c? Though there are some
> > functions which
> > for which this cannot be done.
> > Eg: OF_device_from_xref
> > For this, we will have to use the implementation present in openfirm.c
>
> At least as long as no one implements a replacement, yes.
>
> >
> >
> > On Tue, Aug 18, 2020 at 7:57 AM Chris Johns <chrisj at rtems.org
> > <mailto:chrisj at rtems.org>> wrote:
> >
> >     On 17/8/20 2:57 pm, Niteesh G. S. wrote:
> >     > On Mon, Aug 17, 2020 at 3:49 AM Chris Johns <chrisj at rtems.org
> >     <mailto:chrisj at rtems.org>
> >     > <mailto:chrisj at rtems.org <mailto:chrisj at rtems.org>>> wrote:
> >     >
> >     >     On 16/8/20 11:19 pm, Niteesh G. S. wrote:
> >     >     >
> >     >     > On Sun, Aug 16, 2020 at 2:25 PM Chris Johns
> >     <chrisj at rtems.org <mailto:chrisj at rtems.org>
> >     >     <mailto:chrisj at rtems.org <mailto:chrisj at rtems.org>>
> >     >     > <mailto:chrisj at rtems.org <mailto:chrisj at rtems.org>
> >     <mailto:chrisj at rtems.org <mailto:chrisj at rtems.org>>>> wrote:
> >     >     >
> >     >     >     On 16/8/20 4:49 am, G S Niteesh Babu wrote:
> >     >     >     > ---
> >     >     >
> >     >     >     > +
> >     >     >     > +#ifdef HAVE_CONFIG_H
> >     >     >     > +#include "config.h"
> >     >     >     > +#endif
> >     >     >     > +
> >     >     >     > +#include <bsp/fdt.h>
> >     >     >     > +#include <sys/param.h>
> >     >     >     > +#include <ofw/ofw.h>
> >     >     >     > +#include <libfdt.h>
> >     >     >     > +#include <assert.h>
> >     >     >     > +#include <rtems/sysinit.h>
> >     >     >     > +
> >     >     >     > +const void *fdtp = NULL;
> >     >     >     > +
> >     >     >     > +static phandle_t rtems_fdt_offset_to_phandle( int
> >     offset )
> >     >     >     > +{
> >     >     >     > +  if (offset < 0) {
> >     >     >     > +    return 0;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return (phandle_t)offset + fdt_off_dt_struct(fdtp);
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +static int rtems_fdt_phandle_to_offset( phandle_t
> >     handle )
> >     >     >     > +{
> >     >     >     > +  int off;
> >     >     >     > +  int fdt_off;
> >     >     >     > +
> >     >     >     > +  off = (int) handle;
> >     >     >     > +  fdt_off = fdt_off_dt_struct(fdtp);
> >     >     >     > +
> >     >     >     > +  if (off < fdt_off) {
> >     >     >     > +    return -1;
> >     >     >     > +
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return off - fdt_off;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +static void rtems_ofw_init( void ) {
> >     >     >     > +  int rv;
> >     >     >     > +  const void *fdt;
> >     >     >     > +
> >     >     >     > +  fdt = bsp_fdt_get();
> >     >     >     > +
> >     >     >     > +  rv = fdt_check_header(fdt);
> >     >     >     > +
> >     >     >     > +  /*
> >     >     >     > +   * Is assert a good option to handle error?
> >     >     >     > +   * AFIAK there is no other way to recover from
> >     invalid FDT.
> >     >     >     > +   * On providing an invalid FDT most driver's will
> >     fail/crash anyway.
> >     >     >     > +   */
> >     >     >
> >     >     >     If you want to fail with an error I suggest a documented
> >     internal error. I
> >     >     >     however would prefer we fail in degraded manner but I
> >     understand this
> >     >     may not be
> >     >     >     possible.
> >     >     >
> >     >     >
> >     >     > During the initial discussion, we discussed adding a new
> >     error code in
> >     >     case of an
> >     >     > invalid FDT, something like BSP_INVALID_FDT. I had also sent
> >     a patch but
> >     >     then we
> >     >     > decided not to add one(for some reason that I don't
> >     remember). Instead, use
> >     >     > RTEMS_NOT_CONFIGURED. This has also been used in my previous
> >     OFW patch.
> >     >
> >     >     I am sorry I missed the discussion or I would have commented.
> >     Currently the FDT
> >     >     support in RTEMS is hostile. If you build a u-boot image and
> >     forget to add FDT
> >     >     support added you get a low level crash dump and that is
> >     unfriendly. I woud like
> >     >     to this changed.
> >     >
> >     > So should we add a proper fatal code in case of invalid FDT or FDT
> >     is not provided?
> >     > ARM, POWERPC and RISCV are the only architectures in RTEMS that
> >     use FDT.
> >     > Can we add an FDT check inside start.S before bsp_fdt_copy? and
> >     fail properly in
> >     > case of an invalid FDT.
> >     > Or is it a better idea to add the check inside bsp_fdt_copy but
> >     bsp_fdt_copy is
> >     > optional
> >     > in architectures like ARM, RISCV it is compile time guarded with
> >     > BSP_START_COPY_FDT_FROM_UBOOT
> >
> >     The crash only happens when you run libbsd so I feel the issue is in
> >     there. If
> >     support has been added to libbsd for FDT for a specific arch and BSP
> >     then the
> >     libbsd start up (or what ever) needs to handle the the lack of FDT
> >     support in a
> >     better manner than a crash. This could a console message and an
> >     `exit()` or a
> >     fatal RTEMS error. I am not sure.
> >
> >     I do not want to stall this work for this issue if it can be
> >     resolved else
> >     where. What is not clear to me is how this can be resolved at a
> >     system level and
> >     I would like to see libbsd cleaned up and made a little friendlier
> >     for FDT
> >     support but that is not what this effort is about. I am not across
> >     all the
> >     detail to know what is needed so I hope others will help here.
> >
> >     Chris
> >
> >     >
> >     >     > So should we add a new error code like BSP_INVALID_FDT and
> >     fatal exit or just
> >     >     > use RTEMS_NOT_CONIGURED like the previous patch?
> >     >
> >     >     Not configured is fine with me.
> >     >
> >     >     Chris
> >     >     >
> >     >     >
> >     >     >     > +  assert(rv == 0);
> >     >     >
> >     >     >     I would prefer we did not make this code dependent on
> >     -DNDEBUG.
> >     >     >
> >     >     >     Chris
> >     >     >
> >     >     >     > +
> >     >     >     > +  fdtp = fdt;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +RTEMS_SYSINIT_ITEM(
> >     >     >     > +  rtems_ofw_init,
> >     >     >     > +  RTEMS_SYSINIT_BSP_PRE_DRIVERS,
> >     >     >     > +  RTEMS_SYSINIT_ORDER_FIRST
> >     >     >     > +);
> >     >     >     > +
> >     >     >     > +phandle_t rtems_ofw_peer( phandle_t node )
> >     >     >     > +{
> >     >     >     > +  int offset;
> >     >     >     > +
> >     >     >     > +  if (node == 0) {
> >     >     >     > +    int root = fdt_path_offset(fdtp, "/");
> >     >     >     > +    return rtems_fdt_offset_to_phandle(root);
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  offset = rtems_fdt_phandle_to_offset(node);
> >     >     >     > +  if (offset < 0) {
> >     >     >     > +    return 0;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  offset = fdt_next_subnode(fdtp, offset);
> >     >     >     > +  return rtems_fdt_offset_to_phandle(offset);
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +phandle_t rtems_ofw_child( phandle_t node )
> >     >     >     > +{
> >     >     >     > +  int offset;
> >     >     >     > +
> >     >     >     > +  offset = rtems_fdt_phandle_to_offset(node);
> >     >     >     > +
> >     >     >     > +  if (offset < 0) {
> >     >     >     > +    return 0;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  offset = fdt_first_subnode(fdtp, offset);
> >     >     >     > +  return rtems_fdt_offset_to_phandle(offset);
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +phandle_t rtems_ofw_parent( phandle_t node )
> >     >     >     > +{
> >     >     >     > +  int offset;
> >     >     >     > +
> >     >     >     > +  offset = rtems_fdt_phandle_to_offset(node);
> >     >     >     > +
> >     >     >     > +  if (offset < 0) {
> >     >     >     > +    return 0;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  offset = fdt_parent_offset(fdtp, offset);
> >     >     >     > +  return rtems_fdt_offset_to_phandle(offset);
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +size_t rtems_ofw_get_prop_len(
> >     >     >     > +  phandle_t node,
> >     >     >     > +  const char *propname
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  int offset;
> >     >     >     > +  int len;
> >     >     >     > +  const void *prop;
> >     >     >     > +
> >     >     >     > +  offset = rtems_fdt_phandle_to_offset(node);
> >     >     >     > +
> >     >     >     > +  if (offset < 0) {
> >     >     >     > +    return -1;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  prop = fdt_getprop(fdtp, offset, propname, &len);
> >     >     >     > +
> >     >     >     > +  if (prop == NULL && strcmp(propname, "name") == 0) {
> >     >     >     > +    fdt_get_name(fdtp, offset, &len);
> >     >     >     > +    return len + 1;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  if (prop == NULL && strcmp(propname, "/chosen") ==
> 0) {
> >     >     >     > +    if (strcmp(propname, "fdtbootcpu") == 0)
> >     >     >     > +      return sizeof(pcell_t);
> >     >     >     > +    if (strcmp(propname, "fdtmemreserv") == 0)
> >     >     >     > +      return 2 * sizeof(uint64_t) *
> >     fdt_num_mem_rsv(fdtp);
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  if (prop == NULL) {
> >     >     >     > +    return -1;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return len;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +size_t rtems_ofw_get_prop(
> >     >     >     > +  phandle_t    node,
> >     >     >     > +  const char  *propname,
> >     >     >     > +  void        *buf,
> >     >     >     > +  size_t       bufsize
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  int offset;
> >     >     >     > +  int len;
> >     >     >     > +  const void *prop;
> >     >     >     > +
> >     >     >     > +  offset = rtems_fdt_phandle_to_offset(node);
> >     >     >     > +
> >     >     >     > +  if (offset < 0) {
> >     >     >     > +    return -1;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  prop = fdt_getprop(fdtp, offset, propname, &len);
> >     >     >     > +
> >     >     >     > +  if (prop == NULL && strcmp(propname, "name") == 0) {
> >     >     >     > +    fdt_get_name(fdtp, offset, &len);
> >     >     >     > +    return len + 1;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  if (prop == NULL && strcmp(propname, "/chosen") ==
> 0) {
> >     >     >     > +    if (strcmp(propname, "fdtbootcpu") == 0)
> >     >     >     > +      return sizeof(pcell_t);
> >     >     >     > +    if (strcmp(propname, "fdtmemreserv") == 0)
> >     >     >     > +      return 2 * sizeof(uint64_t) *
> >     fdt_num_mem_rsv(fdtp);
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  if (prop == NULL) {
> >     >     >     > +    return -1;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  bcopy(prop, buf, MIN(len, bufsize));
> >     >     >     > +
> >     >     >     > +  return len;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +size_t rtems_ofw_get_enc_prop(
> >     >     >     > +  phandle_t    node,
> >     >     >     > +  const char  *prop,
> >     >     >     > +  pcell_t     *buf,
> >     >     >     > +  size_t       len
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  size_t rv;
> >     >     >     > +
> >     >     >     > +  assert(len % 4 == 0);
> >     >     >     > +  rv = rtems_ofw_get_prop(node, prop, buf, len);
> >     >     >     > +
> >     >     >     > +  if (rv < 0) {
> >     >     >     > +    return rv;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  for (int i = 0; i < (len / 4); i++) {
> >     >     >     > +    buf[i] = fdt32_to_cpu(buf[i]);
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return rv;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +int rtems_ofw_has_prop(
> >     >     >     > +  phandle_t    node,
> >     >     >     > +  const char  *propname
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  size_t rv;
> >     >     >     > +
> >     >     >     > +  rv = rtems_ofw_get_prop_len(node, propname);
> >     >     >     > +  return rv >= 0 ? 1 : 0;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +size_t rtems_ofw_search_prop(
> >     >     >     > +  phandle_t    node,
> >     >     >     > +  const char  *propname,
> >     >     >     > +  void        *buf,
> >     >     >     > +  size_t       len
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  size_t rv;
> >     >     >     > +
> >     >     >     > +  for (; node != 0; node = rtems_ofw_parent(node)) {
> >     >     >     > +    if ((rv = rtems_ofw_get_prop(node, propname, buf,
> >     len) != -1)) {
> >     >     >     > +      return rv;
> >     >     >     > +    }
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return -1;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +size_t rtems_ofw_search_enc_prop(
> >     >     >     > +  phandle_t    node,
> >     >     >     > +  const char  *propname,
> >     >     >     > +  pcell_t     *buf,
> >     >     >     > +  size_t       len
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  size_t rv;
> >     >     >     > +
> >     >     >     > +  for (; node != 0; node = rtems_ofw_parent(node)) {
> >     >     >     > +    if ((rv = rtems_ofw_get_enc_prop(node, propname,
> >     buf, len) !=
> >     >     -1)) {
> >     >     >     > +      return rv;
> >     >     >     > +    }
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return -1;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +size_t rtems_ofw_get_prop_alloc(
> >     >     >     > +  phandle_t    node,
> >     >     >     > +  const char  *propname,
> >     >     >     > +  void       **buf
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  size_t len;
> >     >     >     > +
> >     >     >     > +  if ((len = rtems_ofw_get_prop_len(node, propname))
> >     == -1) {
> >     >     >     > +    return -1;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  *buf = NULL;
> >     >     >     > +
> >     >     >     > +  if (len > 0) {
> >     >     >     > +    *buf = malloc(len);
> >     >     >     > +
> >     >     >     > +    if (rtems_ofw_get_prop(node, propname, *buf, len)
> >     == -1) {
> >     >     >     > +      rtems_ofw_free(buf);
> >     >     >     > +      *buf = NULL;
> >     >     >     > +      return -1;
> >     >     >     > +    }
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return len;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +size_t rtems_ofw_get_prop_alloc_multi(
> >     >     >     > +  phandle_t    node,
> >     >     >     > +  const char  *propname,
> >     >     >     > +  int          elsz,
> >     >     >     > +  void       **buf
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  size_t len;
> >     >     >     > +
> >     >     >     > +  if ((len = rtems_ofw_get_prop_len(node, propname))
> >     == -1 ||
> >     >     >     > +      (len % elsz != 0)) {
> >     >     >     > +    return -1;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  *buf = NULL;
> >     >     >     > +
> >     >     >     > +  if (len > 0) {
> >     >     >     > +    *buf = malloc(len);
> >     >     >     > +
> >     >     >     > +    if (rtems_ofw_get_prop(node, propname, *buf, len)
> >     == -1) {
> >     >     >     > +      rtems_ofw_free(buf);
> >     >     >     > +      *buf = NULL;
> >     >     >     > +      return -1;
> >     >     >     > +    }
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return (len / elsz);
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +size_t rtems_ofw_get_enc_prop_alloc(
> >     >     >     > +  phandle_t    node,
> >     >     >     > +  const char  *propname,
> >     >     >     > +  void       **buf
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  size_t len;
> >     >     >     > +
> >     >     >     > +  if ((len = rtems_ofw_get_prop_len(node, propname))
> >     == -1) {
> >     >     >     > +    return -1;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  *buf = NULL;
> >     >     >     > +
> >     >     >     > +  if (len > 0) {
> >     >     >     > +    *buf = malloc(len);
> >     >     >     > +
> >     >     >     > +    if (rtems_ofw_get_enc_prop(node, propname, *buf,
> >     len) == -1) {
> >     >     >     > +      rtems_ofw_free(buf);
> >     >     >     > +      *buf = NULL;
> >     >     >     > +      return -1;
> >     >     >     > +    }
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return len;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +size_t rtems_ofw_get_enc_prop_alloc_multi(
> >     >     >     > +  phandle_t     node,
> >     >     >     > +  const char   *propname,
> >     >     >     > +  int           elsz,
> >     >     >     > +  void        **buf
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  size_t len;
> >     >     >     > +
> >     >     >     > +  if ((len = rtems_ofw_get_prop_len(node, propname))
> >     == -1 ||
> >     >     >     > +      (len % elsz != 0)) {
> >     >     >     > +    return -1;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  *buf = NULL;
> >     >     >     > +
> >     >     >     > +  if (len > 0) {
> >     >     >     > +    *buf = malloc(len);
> >     >     >     > +
> >     >     >     > +    if (rtems_ofw_get_enc_prop(node, propname, *buf,
> >     len) == -1) {
> >     >     >     > +      rtems_ofw_free(buf);
> >     >     >     > +      *buf = NULL;
> >     >     >     > +      return -1;
> >     >     >     > +    }
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return (len / elsz);
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +void rtems_ofw_free( void *buf )
> >     >     >     > +{
> >     >     >     > +  free(buf);
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +int rtems_ofw_next_prop(
> >     >     >     > +  phandle_t    node,
> >     >     >     > +  const char  *previous,
> >     >     >     > +  char        *buf,
> >     >     >     > +  size_t       len
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  const void *name;
> >     >     >     > +  const void *prop;
> >     >     >     > +  int offset;
> >     >     >     > +
> >     >     >     > +  offset = rtems_fdt_phandle_to_offset(node);
> >     >     >     > +
> >     >     >     > +  if (offset < 0) {
> >     >     >     > +    return -1;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  if (previous == NULL) {
> >     >     >     > +    offset = fdt_first_property_offset(fdtp, offset);
> >     >     >     > +  } else {
> >     >     >     > +    fdt_for_each_property_offset(offset, fdtp,
> offset) {
> >     >     >     > +      prop = fdt_getprop_by_offset(fdtp, offset,
> >     (const char
> >     >     **)&name, NULL);
> >     >     >     > +      if (prop == NULL)
> >     >     >     > +        return -1;
> >     >     >     > +
> >     >     >     > +      if (strcmp(previous, name) != 0)
> >     >     >     > +        continue;
> >     >     >     > +
> >     >     >     > +      offset = fdt_next_property_offset(fdtp, offset);
> >     >     >     > +      break;
> >     >     >     > +    }
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  if (offset < 0)
> >     >     >     > +    return 0;
> >     >     >     > +
> >     >     >     > +  prop = fdt_getprop_by_offset(fdtp, offset, (const
> >     char **)&name,
> >     >     &offset);
> >     >     >     > +  if (prop == NULL)
> >     >     >     > +    return -1;
> >     >     >     > +
> >     >     >     > +  strncpy(buf, name, len);
> >     >     >     > +
> >     >     >     > +  return 1;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +int rtems_ofw_set_prop(
> >     >     >     > +  phandle_t    node,
> >     >     >     > +  const char  *name,
> >     >     >     > +  const void  *buf,
> >     >     >     > +  size_t       len
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  int offset;
> >     >     >     > +
> >     >     >     > +  offset = rtems_fdt_phandle_to_offset(node);
> >     >     >     > +
> >     >     >     > +  if (offset < 0)
> >     >     >     > +    return -1;
> >     >     >     > +
> >     >     >     > +  if (fdt_setprop_inplace(fdtp, offset, name, buf,
> >     len) != 0)
> >     >     >     > +    return (fdt_setprop(fdtp, offset, name, buf,
> len));
> >     >     >     > +
> >     >     >     > +  return 0;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +phandle_t rtems_ofw_find_device( const char *path )
> >     >     >     > +{
> >     >     >     > +  int offset;
> >     >     >     > +
> >     >     >     > +  offset = fdt_path_offset(fdtp, path);
> >     >     >     > +  if (offset < 0)
> >     >     >     > +    return -1;
> >     >     >     > +
> >     >     >     > +  return rtems_fdt_offset_to_phandle(offset);
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +static phandle_t rtems_ofw_get_effective_phandle(
> >     >     >     > +  phandle_t node,
> >     >     >     > +  phandle_t xref
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  phandle_t child;
> >     >     >     > +  phandle_t ref;
> >     >     >     > +
> >     >     >     > +  for (child = rtems_ofw_child(node); child != 0;
> child =
> >     >     >     rtems_ofw_peer(node)) {
> >     >     >     > +    ref = rtems_ofw_get_effective_phandle(child,
> xref);
> >     >     >     > +    if (ref != -1)
> >     >     >     > +      return ref;
> >     >     >     > +
> >     >     >     > +    if (rtems_ofw_get_enc_prop(child, "phandle",
> >     &ref, sizeof(ref))
> >     >     == -1 &&
> >     >     >     > +        rtems_ofw_get_enc_prop(child, "ibm,phandle",
> >     &ref, sizeof(ref))
> >     >     >     == -1 &&
> >     >     >     > +        rtems_ofw_get_enc_prop(child,
> >     "linux,phandle", &ref,
> >     >     sizeof(ref))
> >     >     >     == -1
> >     >     >     > +    ) {
> >     >     >     > +      continue;
> >     >     >     > +    }
> >     >     >     > +
> >     >     >     > +    if (ref == xref)
> >     >     >     > +      return child;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return -1;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +phandle_t rtems_ofw_node_from_xref( phandle_t xref )
> >     >     >     > +{
> >     >     >     > +  phandle_t node;
> >     >     >     > +
> >     >     >     > +  if ((node =
> >     rtems_ofw_get_effective_phandle(rtems_ofw_peer(0), xref))
> >     >     >     == -1)
> >     >     >     > +    return xref;
> >     >     >     > +
> >     >     >     > +  return node;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +phandle_t rtems_ofw_xref_from_node( phandle_t node )
> >     >     >     > +{
> >     >     >     > +  phandle_t ref;
> >     >     >     > +
> >     >     >     > +    if (rtems_ofw_get_enc_prop(node, "phandle", &ref,
> >     sizeof(ref))
> >     >     == -1 &&
> >     >     >     > +        rtems_ofw_get_enc_prop(node, "ibm,phandle",
> &ref,
> >     >     sizeof(ref)) ==
> >     >     >     -1 &&
> >     >     >     > +        rtems_ofw_get_enc_prop(node, "linux,phandle",
> >     &ref,
> >     >     sizeof(ref))
> >     >     >     == -1)
> >     >     >     > +    {
> >     >     >     > +      return node;
> >     >     >     > +    }
> >     >     >     > +
> >     >     >     > +    return ref;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +phandle_t rtems_ofw_instance_to_package( ihandle_t
> >     instance )
> >     >     >     > +{
> >     >     >     > +  return rtems_ofw_node_from_xref(instance);
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +size_t rtems_ofw_package_to_path(
> >     >     >     > +  phandle_t   node,
> >     >     >     > +  char       *buf,
> >     >     >     > +  size_t      len
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  int offset;
> >     >     >     > +  int rv;
> >     >     >     > +
> >     >     >     > +  offset = rtems_fdt_phandle_to_offset(node);
> >     >     >     > +
> >     >     >     > +  rv = fdt_get_path(fdtp, offset, buf, len);
> >     >     >     > +  if (rv != 0)
> >     >     >     > +    return -1;
> >     >     >     > +
> >     >     >     > +  return rv;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +size_t rtems_ofw_instance_to_path(
> >     >     >     > +  ihandle_t  instance,
> >     >     >     > +  char      *buf,
> >     >     >     > +  size_t     len
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  int offset;
> >     >     >     > +  int rv;
> >     >     >     > +
> >     >     >     > +  offset = rtems_ofw_instance_to_package(instance);
> >     >     >     > +  offset = rtems_fdt_phandle_to_offset(offset);
> >     >     >     > +
> >     >     >     > +  rv = fdt_get_path(fdtp, offset, buf, len);
> >     >     >     > +  if (rv != 0)
> >     >     >     > +    return -1;
> >     >     >     > +
> >     >     >     > +  return rv;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +int rtems_ofw_get_reg(
> >     >     >     > +  phandle_t              node,
> >     >     >     > +  rtems_ofw_memory_area *buf,
> >     >     >     > +  size_t                 size
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  int len;
> >     >     >     > +  int offset;
> >     >     >     > +  int nranges;
> >     >     >     > +  int nregs;
> >     >     >     > +  phandle_t parent;
> >     >     >     > +  rtems_ofw_ranges range;
> >     >     >     > +  const rtems_ofw_ranges *ptr;
> >     >     >     > +
> >     >     >     > +  len = rtems_ofw_get_enc_prop(node, "reg", (pcell_t
> >     *)buf, size);
> >     >     >     > +  if (len <= 0) {
> >     >     >     > +    return len;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  nregs = MIN(len, size) /
> sizeof(rtems_ofw_memory_area);
> >     >     >     > +
> >     >     >     > +  for (parent = rtems_ofw_parent(node); parent > 0;
> >     >     >     > +      parent = rtems_ofw_parent(parent)) {
> >     >     >     > +
> >     >     >     > +    offset = rtems_fdt_phandle_to_offset(parent);
> >     >     >     > +    ptr = fdt_getprop(fdtp, offset, "ranges", &len);
> >     >     >     > +
> >     >     >     > +    if (len < 0) {
> >     >     >     > +      break;
> >     >     >     > +    }
> >     >     >     > +
> >     >     >     > +    nranges = len / sizeof(rtems_ofw_ranges);
> >     >     >     > +
> >     >     >     > +    offset = 0;
> >     >     >     > +    for (int i=0; i < nregs; i++) {
> >     >     >     > +      for (int j=0; j < nranges; j++) {
> >     >     >     > +
> >     >     >     > +        range.parent_bus =
> >     fdt32_to_cpu(ptr[j].parent_bus);
> >     >     >     > +        range.child_bus =
> fdt32_to_cpu(ptr[j].child_bus);
> >     >     >     > +        range.size = fdt32_to_cpu(ptr[j].size);
> >     >     >     > +
> >     >     >     > +        if (buf[i].start >= range.child_bus &&
> >     >     >     > +            buf[i].start < range.child_bus +
> >     range.size) {
> >     >     >     > +          offset = range.parent_bus - range.child_bus;
> >     >     >     > +          break;
> >     >     >     > +        }
> >     >     >     > +
> >     >     >     > +      }
> >     >     >     > +      buf[i].start += offset;
> >     >     >     > +    }
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return nregs;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +int rtems_ofw_get_interrupts(
> >     >     >     > +  phandle_t node,
> >     >     >     > +  void     *buf,
> >     >     >     > +  size_t    size
> >     >     >     > +)
> >     >     >     > +{
> >     >     >     > +  int rv;
> >     >     >     > +
> >     >     >     > +  rv = rtems_ofw_get_enc_prop(node, "interrupts",
> >     buf, size);
> >     >     >     > +  return rv;
> >     >     >     > +}
> >     >     >     > +
> >     >     >     > +bool rtems_ofw_node_status( phandle_t node )
> >     >     >     > +{
> >     >     >     > +  int len;
> >     >     >     > +  const char buf[10];
> >     >     >     > +
> >     >     >     > +  len = rtems_ofw_get_prop(node, "status", &buf[0],
> >     sizeof(buf));
> >     >     >     > +  if ((len == -1) ||
> >     >     >     > +      (strncmp(buf, "okay", MIN(5, len)) == 0) ||
> >     >     >     > +      (strncmp(buf, "ok", MIN(3, len)) == 0)) {
> >     >     >     > +      return true;
> >     >     >     > +  }
> >     >     >     > +
> >     >     >     > +  return false;
> >     >     >     > +}
> >     >     >     > diff --git a/spec/build/bsps/obj.yml
> >     b/spec/build/bsps/obj.yml
> >     >     >     > index 8809238057..141ba25f5e 100644
> >     >     >     > --- a/spec/build/bsps/obj.yml
> >     >     >     > +++ b/spec/build/bsps/obj.yml
> >     >     >     > @@ -24,6 +24,9 @@ install:
> >     >     >     >    - bsps/include/bsp/u-boot.h
> >     >     >     >    - bsps/include/bsp/uart-output-char.h
> >     >     >     >    - bsps/include/bsp/utility.h
> >     >     >     > +- destination: ${BSP_INCLUDEDIR}/ofw
> >     >     >     > +  source:
> >     >     >     > +  - bsps/include/ofw/ofw.h
> >     >     >     >  - destination: ${BSP_INCLUDEDIR}/libchip
> >     >     >     >    source:
> >     >     >     >    - bsps/include/libchip/am29lv160.h
> >     >     >     > @@ -104,4 +107,5 @@ source:
> >     >     >     >  - bsps/shared/dev/serial/z85c30_reg.c
> >     >     >     >  - bsps/shared/start/bootcard.c
> >     >     >     >  - bsps/shared/rtems-version.c
> >     >     >     > +- bsps/shared/ofw/ofw.c
> >     >     >     >  type: build
> >     >     >     >
> >     >     >
> >     >
> >
> >
> > _______________________________________________
> > devel mailing list
> > devel at rtems.org
> > http://lists.rtems.org/mailman/listinfo/devel
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20200818/d8b2fcfd/attachment-0001.html>


More information about the devel mailing list