OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [ppc/] [pk_disklabel.c] - Diff between revs 834 and 842

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 834 Rev 842
/*  This file is part of the program psim.
/*  This file is part of the program psim.
 
 
    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
 
 
    This program is free software; you can redistribute it and/or modify
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    (at your option) any later version.
 
 
    This program is distributed in the hope that it will be useful,
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    GNU General Public License for more details.
 
 
    You should have received a copy of the GNU General Public License
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 
    */
    */
 
 
 
 
#ifndef _PK_DISKLABEL_C_
#ifndef _PK_DISKLABEL_C_
#define _PK_DISKLABEL_C_
#define _PK_DISKLABEL_C_
 
 
#ifndef STATIC_INLINE_PK_DISKLABEL
#ifndef STATIC_INLINE_PK_DISKLABEL
#define STATIC_INLINE_PK_DISKLABEL STATIC_INLINE
#define STATIC_INLINE_PK_DISKLABEL STATIC_INLINE
#endif
#endif
 
 
#include "device_table.h"
#include "device_table.h"
 
 
#include "pk.h"
#include "pk.h"
 
 
#ifdef HAVE_STDLIB_H
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#include <stdlib.h>
#endif
#endif
 
 
 
 
 
 
/* PACKAGE
/* PACKAGE
 
 
   disk-label - all knowing disk I/O package
   disk-label - all knowing disk I/O package
 
 
   DESCRIPTION
   DESCRIPTION
 
 
   The disk-label package provides a generic interface to disk
   The disk-label package provides a generic interface to disk
   devices.  It uses the arguments specified when an instance is being
   devices.  It uses the arguments specified when an instance is being
   created to determine if the raw disk, a partition, or a file within
   created to determine if the raw disk, a partition, or a file within
   a partition should be opened.
   a partition should be opened.
 
 
   An instance create call to disk-label could result, for instance,
   An instance create call to disk-label could result, for instance,
   in the opening of a DOS file system contained within a dos
   in the opening of a DOS file system contained within a dos
   partition contained within a physical disk.
   partition contained within a physical disk.
 
 
   */
   */
 
 
/* taken from bfd/ppcboot.c by Michael Meissner */
/* taken from bfd/ppcboot.c by Michael Meissner */
 
 
/* PPCbug location structure */
/* PPCbug location structure */
typedef struct ppcboot_location {
typedef struct ppcboot_location {
  unsigned8 ind;
  unsigned8 ind;
  unsigned8 head;
  unsigned8 head;
  unsigned8 sector;
  unsigned8 sector;
  unsigned8 cylinder;
  unsigned8 cylinder;
} ppcboot_location_t;
} ppcboot_location_t;
 
 
/* PPCbug partition table layout */
/* PPCbug partition table layout */
typedef struct ppcboot_partition {
typedef struct ppcboot_partition {
  ppcboot_location_t partition_begin;   /* partition begin */
  ppcboot_location_t partition_begin;   /* partition begin */
  ppcboot_location_t partition_end;     /* partition end */
  ppcboot_location_t partition_end;     /* partition end */
  unsigned8 sector_begin[4];            /* 32-bit start RBA (zero-based), little endian */
  unsigned8 sector_begin[4];            /* 32-bit start RBA (zero-based), little endian */
  unsigned8 sector_length[4];           /* 32-bit RBA count (one-based), little endian */
  unsigned8 sector_length[4];           /* 32-bit RBA count (one-based), little endian */
} ppcboot_partition_t;
} ppcboot_partition_t;
 
 
#if 0
#if 0
/* PPCbug boot layout.  */
/* PPCbug boot layout.  */
typedef struct ppcboot_hdr {
typedef struct ppcboot_hdr {
  unsigned8             pc_compatibility[446];  /* x86 instruction field */
  unsigned8             pc_compatibility[446];  /* x86 instruction field */
  ppcboot_partition_t   partition[4];           /* partition information */
  ppcboot_partition_t   partition[4];           /* partition information */
  unsigned8             signature[2];           /* 0x55 and 0xaa */
  unsigned8             signature[2];           /* 0x55 and 0xaa */
  unsigned8             entry_offset[4];        /* entry point offset, little endian */
  unsigned8             entry_offset[4];        /* entry point offset, little endian */
  unsigned8             length[4];              /* load image length, little endian */
  unsigned8             length[4];              /* load image length, little endian */
  unsigned8             flags;                  /* flag field */
  unsigned8             flags;                  /* flag field */
  unsigned8             os_id;                  /* OS_ID */
  unsigned8             os_id;                  /* OS_ID */
  char                  partition_name[32];     /* partition name */
  char                  partition_name[32];     /* partition name */
  unsigned8             reserved1[470];         /* reserved */
  unsigned8             reserved1[470];         /* reserved */
} ppcboot_hdr_t;
} ppcboot_hdr_t;
#endif
#endif
 
 
 
 
typedef struct _disklabel {
typedef struct _disklabel {
  device_instance *parent;
  device_instance *parent;
  device_instance *raw_disk;
  device_instance *raw_disk;
  unsigned_word pos;
  unsigned_word pos;
  unsigned_word sector_begin;
  unsigned_word sector_begin;
  unsigned_word sector_length;
  unsigned_word sector_length;
} disklabel;
} disklabel;
 
 
 
 
static unsigned_word
static unsigned_word
sector2uw(unsigned8 s[4])
sector2uw(unsigned8 s[4])
{
{
  return ((s[3] << 24)
  return ((s[3] << 24)
          + (s[2] << 16)
          + (s[2] << 16)
          + (s[1] << 8)
          + (s[1] << 8)
          + (s[0] << 0));
          + (s[0] << 0));
}
}
 
 
 
 
static void
static void
disklabel_delete(device_instance *instance)
disklabel_delete(device_instance *instance)
{
{
  disklabel *label = device_instance_data(instance);
  disklabel *label = device_instance_data(instance);
  device_instance_delete(label->raw_disk);
  device_instance_delete(label->raw_disk);
  zfree(label);
  zfree(label);
}
}
 
 
 
 
static int
static int
disklabel_read(device_instance *instance,
disklabel_read(device_instance *instance,
               void *buf,
               void *buf,
               unsigned_word len)
               unsigned_word len)
{
{
  disklabel *label = device_instance_data(instance);
  disklabel *label = device_instance_data(instance);
  int nr_read;
  int nr_read;
  if (label->pos + len > label->sector_length)
  if (label->pos + len > label->sector_length)
    len = label->sector_length - label->pos;
    len = label->sector_length - label->pos;
  if (device_instance_seek(label->raw_disk, 0,
  if (device_instance_seek(label->raw_disk, 0,
                           label->sector_begin + label->pos) < 0)
                           label->sector_begin + label->pos) < 0)
    return -1;
    return -1;
  nr_read = device_instance_read(label->raw_disk, buf, len);
  nr_read = device_instance_read(label->raw_disk, buf, len);
  if (nr_read > 0)
  if (nr_read > 0)
    label->pos += nr_read;
    label->pos += nr_read;
  return nr_read;
  return nr_read;
}
}
 
 
static int
static int
disklabel_write(device_instance *instance,
disklabel_write(device_instance *instance,
                const void *buf,
                const void *buf,
                unsigned_word len)
                unsigned_word len)
{
{
  disklabel *label = device_instance_data(instance);
  disklabel *label = device_instance_data(instance);
  int nr_written;
  int nr_written;
  if (label->pos + len > label->sector_length)
  if (label->pos + len > label->sector_length)
    len = label->sector_length - label->pos;
    len = label->sector_length - label->pos;
  if (device_instance_seek(label->raw_disk, 0,
  if (device_instance_seek(label->raw_disk, 0,
                           label->sector_begin + label->pos) < 0)
                           label->sector_begin + label->pos) < 0)
    return -1;
    return -1;
  nr_written = device_instance_write(label->raw_disk, buf, len);
  nr_written = device_instance_write(label->raw_disk, buf, len);
  if (nr_written > 0)
  if (nr_written > 0)
    label->pos += nr_written;
    label->pos += nr_written;
  return nr_written;
  return nr_written;
}
}
 
 
static int
static int
disklabel_seek(device_instance *instance,
disklabel_seek(device_instance *instance,
               unsigned_word pos_hi,
               unsigned_word pos_hi,
               unsigned_word pos_lo)
               unsigned_word pos_lo)
{
{
  disklabel *label = device_instance_data(instance);
  disklabel *label = device_instance_data(instance);
  if (pos_lo >= label->sector_length || pos_hi != 0)
  if (pos_lo >= label->sector_length || pos_hi != 0)
    return -1;
    return -1;
  label->pos = pos_lo;
  label->pos = pos_lo;
  return 0;
  return 0;
}
}
 
 
 
 
static const device_instance_callbacks package_disklabel_callbacks = {
static const device_instance_callbacks package_disklabel_callbacks = {
  disklabel_delete,
  disklabel_delete,
  disklabel_read,
  disklabel_read,
  disklabel_write,
  disklabel_write,
  disklabel_seek,
  disklabel_seek,
};
};
 
 
/* Reconize different types of boot block */
/* Reconize different types of boot block */
 
 
static int
static int
block0_is_bpb(const unsigned8 block[])
block0_is_bpb(const unsigned8 block[])
{
{
  const char ebdic_ibma[] = { 0xc9, 0xc2, 0xd4, 0xc1 };
  const char ebdic_ibma[] = { 0xc9, 0xc2, 0xd4, 0xc1 };
  /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
  /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
  /* can't start with IBMA */
  /* can't start with IBMA */
  if (memcmp(block, ebdic_ibma, sizeof(ebdic_ibma)) == 0)
  if (memcmp(block, ebdic_ibma, sizeof(ebdic_ibma)) == 0)
    return 0;
    return 0;
  /* must have LE 0xAA55 signature at offset 510 */
  /* must have LE 0xAA55 signature at offset 510 */
  if (block[511] != 0xAA && block[510] != 0x55)
  if (block[511] != 0xAA && block[510] != 0x55)
    return 0;
    return 0;
  /* valid 16 bit LE bytes per sector - 256, 512, 1024 */
  /* valid 16 bit LE bytes per sector - 256, 512, 1024 */
  if (block[11] != 0
  if (block[11] != 0
      || (block[12] != 1 && block[12] != 2 && block[12] != 4))
      || (block[12] != 1 && block[12] != 2 && block[12] != 4))
    return 0;
    return 0;
  /* nr fats is 1 or 2 */
  /* nr fats is 1 or 2 */
  if (block[16] != 1 && block[16] != 2)
  if (block[16] != 1 && block[16] != 2)
    return 0;
    return 0;
  return 1;
  return 1;
}
}
 
 
 
 
/* Verify that the device contains an ISO-9660 File system */
/* Verify that the device contains an ISO-9660 File system */
 
 
static int
static int
is_iso9660(device_instance *raw_disk)
is_iso9660(device_instance *raw_disk)
{
{
  /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
  /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
  unsigned8 block[512];
  unsigned8 block[512];
  if (device_instance_seek(raw_disk, 0, 512 * 64) < 0)
  if (device_instance_seek(raw_disk, 0, 512 * 64) < 0)
    return 0;
    return 0;
  if (device_instance_read(raw_disk, block, sizeof(block)) != sizeof(block))
  if (device_instance_read(raw_disk, block, sizeof(block)) != sizeof(block))
    return 0;
    return 0;
  if (block[0] == 0x01
  if (block[0] == 0x01
      && block[1] == 'C'
      && block[1] == 'C'
      && block[2] == 'D'
      && block[2] == 'D'
      && block[3] == '0'
      && block[3] == '0'
      && block[4] == '0'
      && block[4] == '0'
      && block[5] == '1')
      && block[5] == '1')
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 
/* Verify that the disk block contains a valid DOS partition table.
/* Verify that the disk block contains a valid DOS partition table.
   While we're at it have a look around for active partitions etc.
   While we're at it have a look around for active partitions etc.
 
 
   Return 0: invalid
   Return 0: invalid
   Return 1..4: valid, value returned is the first active partition
   Return 1..4: valid, value returned is the first active partition
   Return -1: no active partition */
   Return -1: no active partition */
 
 
static int
static int
block0_is_fdisk(const unsigned8 block[])
block0_is_fdisk(const unsigned8 block[])
{
{
  const int partition_type_fields[] = { 0, 0x1c2, 0x1d2, 0x1e2, 0x1f2 };
  const int partition_type_fields[] = { 0, 0x1c2, 0x1d2, 0x1e2, 0x1f2 };
  const int partition_active_fields[] = { 0, 0x1be, 0x1ce, 0x1de, 0xee };
  const int partition_active_fields[] = { 0, 0x1be, 0x1ce, 0x1de, 0xee };
  int partition;
  int partition;
  int active = -1;
  int active = -1;
  /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
  /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
  /* must have LE 0xAA55 signature at offset 510 */
  /* must have LE 0xAA55 signature at offset 510 */
  if (block[511/*0x1ff*/] != 0xAA && block[510/*0x1fe*/] != 0x55)
  if (block[511/*0x1ff*/] != 0xAA && block[510/*0x1fe*/] != 0x55)
    return 0;
    return 0;
  /* must contain valid partition types */
  /* must contain valid partition types */
  for (partition = 1; partition <= 4 && active != 0; partition++) {
  for (partition = 1; partition <= 4 && active != 0; partition++) {
    int partition_type = block[partition_type_fields[partition]];
    int partition_type = block[partition_type_fields[partition]];
    int is_active = block[partition_active_fields[partition]] == 0x80;
    int is_active = block[partition_active_fields[partition]] == 0x80;
    const char *type;
    const char *type;
    switch (partition_type) {
    switch (partition_type) {
    case 0x00:
    case 0x00:
      type = "UNUSED";
      type = "UNUSED";
      break;
      break;
    case 0x01:
    case 0x01:
      type = "FAT 12 File system";
      type = "FAT 12 File system";
      break;
      break;
    case 0x04:
    case 0x04:
      type = "FAT 16 File system";
      type = "FAT 16 File system";
      break;
      break;
    case 0x05:
    case 0x05:
    case 0x06:
    case 0x06:
      type = "rejected - extended/chained partition not supported";
      type = "rejected - extended/chained partition not supported";
      active = 0;
      active = 0;
      break;
      break;
    case 0x41:
    case 0x41:
      type = "Single program image";
      type = "Single program image";
      break;
      break;
    case 0x82:
    case 0x82:
      type = "Solaris?";
      type = "Solaris?";
      break;
      break;
    case 0x96:
    case 0x96:
      type = "ISO 9660 File system";
      type = "ISO 9660 File system";
      break;
      break;
    default:
    default:
      type = "rejected - unknown type";
      type = "rejected - unknown type";
      active = 0;
      active = 0;
      break;
      break;
    }
    }
    PTRACE(disklabel, ("partition %d of type 0x%02x - %s%s\n",
    PTRACE(disklabel, ("partition %d of type 0x%02x - %s%s\n",
                       partition,
                       partition,
                       partition_type,
                       partition_type,
                       type,
                       type,
                       is_active && active != 0 ? " (active)" : ""));
                       is_active && active != 0 ? " (active)" : ""));
    if (partition_type != 0 && is_active && active < 0)
    if (partition_type != 0 && is_active && active < 0)
      active = partition;
      active = partition;
  }
  }
  return active;
  return active;
}
}
 
 
 
 
/* Verify that block0 corresponds to a MAC disk */
/* Verify that block0 corresponds to a MAC disk */
 
 
static int
static int
block0_is_mac_disk(const unsigned8 block[])
block0_is_mac_disk(const unsigned8 block[])
{
{
  /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
  /* ref PowerPC Microprocessor CHRP bindings 1.2b - page 47 */
  /* signature - BEx4552 at offset 0 */
  /* signature - BEx4552 at offset 0 */
  if (block[0] != 0x45 || block[1] != 0x52)
  if (block[0] != 0x45 || block[1] != 0x52)
    return 0;
    return 0;
  return 1;
  return 1;
}
}
 
 
 
 
/* Open a logical disk/file */
/* Open a logical disk/file */
 
 
device_instance *
device_instance *
pk_disklabel_create_instance(device_instance *raw_disk,
pk_disklabel_create_instance(device_instance *raw_disk,
                             const char *args)
                             const char *args)
{
{
  int partition;
  int partition;
  char *filename;
  char *filename;
 
 
  /* parse the arguments */
  /* parse the arguments */
  if (args == NULL) {
  if (args == NULL) {
    partition = 0;
    partition = 0;
    filename = NULL;
    filename = NULL;
  }
  }
  else {
  else {
    partition = strtoul((char*)args, &filename, 0);
    partition = strtoul((char*)args, &filename, 0);
    if (filename == args)
    if (filename == args)
      partition = -1; /* not specified */
      partition = -1; /* not specified */
    if (*filename == ',')
    if (*filename == ',')
      filename++;
      filename++;
    if (*filename == '\0')
    if (*filename == '\0')
      filename = NULL; /* easier */
      filename = NULL; /* easier */
  }
  }
 
 
  if (partition == 0) {
  if (partition == 0) {
    /* select the raw disk */
    /* select the raw disk */
    return raw_disk;
    return raw_disk;
  }
  }
  else {
  else {
    unsigned8 boot_block[512];
    unsigned8 boot_block[512];
    /* get the boot block for examination */
    /* get the boot block for examination */
    if (device_instance_seek(raw_disk, 0, 0) < 0)
    if (device_instance_seek(raw_disk, 0, 0) < 0)
      device_error(device_instance_device(raw_disk),
      device_error(device_instance_device(raw_disk),
                   "Problem seeking on raw disk");
                   "Problem seeking on raw disk");
    if (device_instance_read(raw_disk, &boot_block, sizeof(boot_block))
    if (device_instance_read(raw_disk, &boot_block, sizeof(boot_block))
        != sizeof(boot_block))
        != sizeof(boot_block))
      device_error(device_instance_device(raw_disk), "Problem reading boot block");
      device_error(device_instance_device(raw_disk), "Problem reading boot block");
 
 
    if (partition < 0) {
    if (partition < 0) {
      /* select the active partition */
      /* select the active partition */
      if (block0_is_bpb(boot_block)) {
      if (block0_is_bpb(boot_block)) {
        device_error(device_instance_device(raw_disk), "Unimplemented active BPB");
        device_error(device_instance_device(raw_disk), "Unimplemented active BPB");
      }
      }
      else if (block0_is_fdisk(boot_block)) {
      else if (block0_is_fdisk(boot_block)) {
        int active = block0_is_fdisk(boot_block);
        int active = block0_is_fdisk(boot_block);
        device_error(device_instance_device(raw_disk), "Unimplemented active FDISK (%d)",
        device_error(device_instance_device(raw_disk), "Unimplemented active FDISK (%d)",
                     active);
                     active);
      }
      }
      else if (is_iso9660(raw_disk)) {
      else if (is_iso9660(raw_disk)) {
        device_error(device_instance_device(raw_disk), "Unimplemented active ISO9660");
        device_error(device_instance_device(raw_disk), "Unimplemented active ISO9660");
      }
      }
      else if (block0_is_mac_disk(boot_block)) {
      else if (block0_is_mac_disk(boot_block)) {
        device_error(device_instance_device(raw_disk), "Unimplemented active MAC DISK");
        device_error(device_instance_device(raw_disk), "Unimplemented active MAC DISK");
      }
      }
      else {
      else {
        device_error(device_instance_device(raw_disk), "Unreconized bootblock");
        device_error(device_instance_device(raw_disk), "Unreconized bootblock");
      }
      }
    }
    }
    else {
    else {
      /* select the specified disk partition */
      /* select the specified disk partition */
      if (block0_is_bpb(boot_block)) {
      if (block0_is_bpb(boot_block)) {
        device_error(device_instance_device(raw_disk), "Unimplemented BPB");
        device_error(device_instance_device(raw_disk), "Unimplemented BPB");
      }
      }
      else if (block0_is_fdisk(boot_block)) {
      else if (block0_is_fdisk(boot_block)) {
        /* return an instance */
        /* return an instance */
        ppcboot_partition_t *partition_table = (ppcboot_partition_t*) &boot_block[446];
        ppcboot_partition_t *partition_table = (ppcboot_partition_t*) &boot_block[446];
        ppcboot_partition_t *partition_entry;
        ppcboot_partition_t *partition_entry;
        disklabel *label;
        disklabel *label;
        if (partition > 4)
        if (partition > 4)
          device_error(device_instance_device(raw_disk),
          device_error(device_instance_device(raw_disk),
                       "Only FDISK partitions 1..4 supported");
                       "Only FDISK partitions 1..4 supported");
        partition_entry = &partition_table[partition - 1];
        partition_entry = &partition_table[partition - 1];
        label = ZALLOC(disklabel);
        label = ZALLOC(disklabel);
        label->raw_disk = raw_disk;
        label->raw_disk = raw_disk;
        label->pos = 0;
        label->pos = 0;
        label->sector_begin = 512 * sector2uw(partition_entry->sector_begin);
        label->sector_begin = 512 * sector2uw(partition_entry->sector_begin);
        label->sector_length = 512 * sector2uw(partition_entry->sector_length);
        label->sector_length = 512 * sector2uw(partition_entry->sector_length);
        PTRACE(disklabel, ("partition %ld, sector-begin %ld, length %ld\n",
        PTRACE(disklabel, ("partition %ld, sector-begin %ld, length %ld\n",
                           (long)partition,
                           (long)partition,
                           (long)label->sector_begin,
                           (long)label->sector_begin,
                           (long)label->sector_length));
                           (long)label->sector_length));
        if (filename != NULL)
        if (filename != NULL)
          device_error(device_instance_device(raw_disk),
          device_error(device_instance_device(raw_disk),
                       "FDISK file names not yet supported");
                       "FDISK file names not yet supported");
        return device_create_instance_from(NULL, raw_disk,
        return device_create_instance_from(NULL, raw_disk,
                                           label,
                                           label,
                                           NULL, args,
                                           NULL, args,
                                           &package_disklabel_callbacks);
                                           &package_disklabel_callbacks);
      }
      }
      else if (block0_is_mac_disk(boot_block)) {
      else if (block0_is_mac_disk(boot_block)) {
        device_error(device_instance_device(raw_disk), "Unimplemented MAC DISK");
        device_error(device_instance_device(raw_disk), "Unimplemented MAC DISK");
      }
      }
      else {
      else {
        device_error(device_instance_device(raw_disk),
        device_error(device_instance_device(raw_disk),
                     "Unreconized bootblock");
                     "Unreconized bootblock");
      }
      }
    }
    }
  }
  }
 
 
  return NULL;
  return NULL;
}
}
 
 
 
 
#endif /* _PK_DISKLABEL_C_ */
#endif /* _PK_DISKLABEL_C_ */
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.