summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwill_kuo <[email protected]>2020-09-08 18:39:01 +0800
committerAlex Doyle <[email protected]>2020-09-11 09:46:21 -0700
commit19c38c19df3c36215051ec984d564041713d21d8 (patch)
tree88ad7ad2e0f9e5ed06bca7b43acb7c930ace66ed
parentb5adc201df4b4a74d72a937bb37a1fe49a25e5f4 (diff)
Quanta: Add support for QuantaMesh COME CPU board
================================================================================ QuantaMesh COME CPU board (Broadwell-DE) ================================================================================ QuantaMesh switch which supports modularized CPU board design, have a non-programmable H/W component for mother board detection. For motherboard detection, please refer to ``busybox/miscutils/mb_detect.c`` Supported Platforms ======================= - T7040-IXAE (cpu module) 40x100G QSFP28 ports - T7080-IXA (cpu module) 80x100G QSFP28 ports - For more detail product information, please refer to https://qct.io/ Specification ================= - Modularized CPU board design - 1 RJ-45 out-of-band management port (10/100/1000M) - 1 RJ-45 console port - 1 2x16GB DDR4 SDRAM - 1 M.2 NVMe SSD 128GB, maximum to 2x256GB - 1 USB 2.0 port Signed-off-by: Will Kuo <[email protected]> Signed-off-by: Alex Doyle <[email protected]>
-rw-r--r--build-config/scripts/onie-build-targets.json1
-rw-r--r--machine/quanta/quanta_come/INSTALL166
-rw-r--r--machine/quanta/quanta_come/build.sh14
-rw-r--r--machine/quanta/quanta_come/busybox/conf/config7
-rw-r--r--machine/quanta/quanta_come/busybox/patches/onie-sys-eeprom-come-platform.patch656
-rw-r--r--machine/quanta/quanta_come/busybox/patches/series1
-rw-r--r--machine/quanta/quanta_come/demo/platform.conf1
-rw-r--r--machine/quanta/quanta_come/installer.conf107
-rw-r--r--machine/quanta/quanta_come/installer/install-platform20
-rw-r--r--machine/quanta/quanta_come/kernel/config30
-rw-r--r--machine/quanta/quanta_come/kernel/drivers-hid-hid_quirks.patch12
-rw-r--r--machine/quanta/quanta_come/kernel/series1
-rw-r--r--machine/quanta/quanta_come/machine.make79
-rw-r--r--machine/quanta/quanta_come/rootconf/sysroot-lib-onie/gen-config-platform27
-rw-r--r--machine/quanta/quanta_come/rootconf/sysroot-lib-onie/sysinfo-platform16
15 files changed, 1138 insertions, 0 deletions
diff --git a/build-config/scripts/onie-build-targets.json b/build-config/scripts/onie-build-targets.json
index 9a8d18c6..1b179208 100644
--- a/build-config/scripts/onie-build-targets.json
+++ b/build-config/scripts/onie-build-targets.json
@@ -222,6 +222,7 @@
{ "Vendor": "quanta", "Platform": "quanta_common_rangeley", "BuildEnv": "Debian9", "Release": "2020.05br", "Architecture": "amd64", "Notes": "No notes." },
{ "Vendor": "quanta", "Platform": "quanta_common_rglbmc", "BuildEnv": "Debian9", "Release": "2020.05br", "Architecture": "amd64", "Notes": "No notes." },
{ "Vendor": "quanta", "Platform": "quanta_dnv", "BuildEnv": "Debian9", "Release": "2020.05br", "Architecture": "amd64", "Notes": "No notes." },
+ { "Vendor": "quanta", "Platform": "quanta_come", "BuildEnv": "Debian9", "Release": "2020.08br", "Architecture": "amd64", "Notes": "No notes." },
{ "Vendor": "quanta", "Platform": "quanta_lb8d", "BuildEnv": "Debian9", "Release": "None", "Architecture": "PowerPC", "Notes": "Image size exceeds maximum." },
{ "Vendor": "quanta", "Platform": "quanta_lb9", "BuildEnv": "Debian9", "Release": "2020.05br", "Architecture": "PowerPC", "Notes": "No notes." },
{ "Vendor": "quanta", "Platform": "quanta_ly2", "BuildEnv": "Debian9", "Release": "2020.05br", "Architecture": "PowerPC", "Notes": "No notes." },
diff --git a/machine/quanta/quanta_come/INSTALL b/machine/quanta/quanta_come/INSTALL
new file mode 100644
index 00000000..888f7df1
--- /dev/null
+++ b/machine/quanta/quanta_come/INSTALL
@@ -0,0 +1,166 @@
+Add support for QuantaMesh COME CPU board (Broadwell-DE)
+
+================================================================================
+ QuantaMesh COME CPU board (Broadwell-DE)
+================================================================================
+
+ QuantaMesh switch which supports modularized CPU board design, have a
+non-programmable H/W component for mother board detection. For motherboard
+detection, please refer to ``busybox/miscutils/mb_detect.c``
+
+ Supported Platforms
+=======================
+ - T7040-IXAE (cpu module)
+ 40x100G QSFP28 ports
+
+ - T7080-IXA (cpu module)
+ 80x100G QSFP28 ports
+
+ - For more detail product information, please refer to
+ https://qct.io/
+
+ Specification
+=================
+ - Modularized CPU board design
+ - 1 RJ-45 out-of-band management port (10/100/1000M)
+ - 1 RJ-45 console port
+ - 1 2x16GB DDR4 SDRAM
+ - 1 M.2 NVMe SSD 128GB, maximum to 2x256GB
+ - 1 USB 2.0 port
+
+============================================================
+Installing ONIE on Quanta COME CPU board
+============================================================
+
+Cross-Compiling ONIE
+====================
+
+To compile ONIE first change directories to ``build-config`` and then
+type ``"make MACHINEROOT=../machine/quanta/ MACHINE=quanta_come all"``. For example::
+
+ $ cd build-config
+ $ make -j4 MACHINEROOT=../machine/quanta/ MACHINE=quanta_come all
+
+Or, change directories to ``machine/quanta/quanta_come`` to compile ONIE,
+use ``build.sh`` to compile ONIE. For example:
+
+ $ cd machine/quanta/quanta_bwde
+ $ ./build.sh all
+
+When complete, the ONIE binaries are located in
+``build/images``::
+
+-rw-r--r-- 1 32050176 Sep 7 08:26 onie-recovery-x86_64-quanta_come-r0.efi64.pxe
+-rw-r--r-- 1 29491200 Sep 7 08:26 onie-recovery-x86_64-quanta_come-r0.iso
+-rw-r--r-- 1 12894071 Sep 7 08:25 onie-updater-x86_64-quanta_come-r0
+-rw-r--r-- 1 9267968 Sep 7 08:25 quanta_come-r0.initrd
+-rw-r--r-- 1 3559904 Sep 7 03:39 quanta_come-r0.vmlinuz
+
+quanta_come-r0.vmlinuz -- This is the ONIE kernel image
+
+quanta_come-r0.initrd -- This is the ONIE initramfs (filesystem)
+
+onie-updater-x86_64-quanta_come-r0 -- This is the ONIE self-update
+image. This image is a self-extracting archive used for installing
+ONIE.
+
+onie-recovery-x86_64-quanta_come-r0.iso -- This is a recovery ISO image
+that can be installed as a CDROM image.
+
+onie-recovery-x86_64-quanta_come-r0.efi64.pxe -- This is the UEFI PXE image
+that can be installed through UEFI PXE.
+First of all, setup NEXTSERVER as tftp server ip,
+and BOOTFILE as ``onie-recovery-x86_64-quanta_come-r0.efi64.pxe`` in dhcp server.
+While seeing ``Press <ESC> to skip...``, press <ESC> then 2 to enter setup.
+Switch to ``Save & Exit`` tab, you may see
+``UEFI: NIC1 IPv4 Intel(R) Ethernet Connection``, or
+``UEFI: NIC1 IPv6 Intel(R) Ethernet Connection`` to execute UEFI PXE
+The screenshot of BIOS as below.
+
+================================================================================
+
+CPU: Intel(R) Xeon(R) CPU D-1548 @ 2.00GHz Speed: 2000MHz
+Total Memory: 32768MB (DDR4)-2133MHz
+
+USB Devices total: 0 KBDs, 0 MICE, 1 MASS, 3 HUBs
+
+Detected ATA/ATAPI Devices...
+
+
+Version 2.19.1269. Copyright (C) 2020 American Megatrends, Inc.
+BIOS Date: 06/22/2020 18:23:36 Ver: 2A00
+Press <DEL> or <F2> to enter setup.
+Press <F11> for BBS POPUP menu.
+Press <F12> if you want to boot from the network.
+
+
+
+
+
+
+
+
+
+
+
+Press <ESC> to skip...5 A9
+
+
+================================================================================
+
+ Aptio Setup Utility - Copyright (C) 2020 American Megatrends, Inc.
+ Main Advanced Server Mgmt Boot Security Save & Exit
+������������������������������������������������������������������������������?
+? BIOS Information ?et the Date. Use Tab ?
+? BIOS Vendor American Megatrends ?o switch between Data ?
+? Core Version 5.11 ?lements. ?
+? Compliancy UEFI 2.4; PI 1.3 ? ?
+? Project Version 2A00 ? ?
+? Build Date and Time 06/22/2020 18:23:36 ? ?
+? ? ?
+? Memory Information ? ?
+? Total Memory 32768 MB (DDR4) ? ?
+? ������������������������?
+? System Date [Mon 09/07/2020] ?<: Select Screen ?
+? System Time [00:13:32] ? Select Item ?
+? ?nter: Select ?
+? Access Level Administrator ?/-: Change Opt. ?
+? ?1: Help for more Keys ?
+? ?8: Previous Values ?
+? ?9: Optimized Defaults ?
+? ?10: Save & Reset ?
+? ?SC: Exit ?
+��������������������������������������������������������������������������������
+ Version 2.19.1269. Copyright (C) 2020 American Megatrends, Inc.
+ AB
+
+================================================================================
+
+ Aptio Setup Utility - Copyright (C) 2020 American Megatrends, Inc.
+ Main Advanced Server Mgmt Boot Security Save & Exit
+������������������������������������������������������������������������������?
+? Discard Changes and Exit ?xit system setup ?
+? Save Changes and Reset ?ithout saving any ?
+? ?hanges. ?
+? Discard Changes ? ?
+? ? ?
+? Restore Defaults ? ?
+? Save as User Defaults ? ?
+? Restore User Defaults ? ?
+? ? ?
+? Boot Override ������������������������?
+? ONIE: Open Network Install Environment ?<: Select Screen ?
+? (TS128GMTE550T) ? Select Item ?
+? UEFI: IPv6 Intel(R) I210 Gigabit Network ?nter: Select ?
+? Connection ?/-: Change Opt. ?
+? UEFI: IPv4 Intel(R) I210 Gigabit Network ?1: Help for more Keys ?
+? Connection ?8: Previous Values ?
+? UEFI: Built-in EFI Shell ?9: Optimized Defaults ?
+? ?10: Save & Reset ?
+? ?SC: Exit ?
+��������������������������������������������������������������������������������
+ Version 2.19.1269. Copyright (C) 2020 American Megatrends, Inc.
+ AB
+
+================================================================================
+
diff --git a/machine/quanta/quanta_come/build.sh b/machine/quanta/quanta_come/build.sh
new file mode 100644
index 00000000..4148587e
--- /dev/null
+++ b/machine/quanta/quanta_come/build.sh
@@ -0,0 +1,14 @@
+ONIE_ROOT=$(realpath $(dirname $0)/../../../)
+MACHINE=$(basename $(dirname $(realpath $0)))
+MACHINEROOT=$ONIE_ROOT/machine/quanta
+PARAMS=$*
+PARAMS=${PARAMS:-help}
+BUILD_IMAGE=$ONIE_ROOT/build/images
+
+make -C $ONIE_ROOT/build-config MACHINE=$MACHINE MACHINEROOT=$MACHINEROOT $PARAMS
+
+if [[ $PARAMS =~ .*all.* ]] || [[ $PARAMS =~ .*demo.* ]]; then
+ echo "Build images path: $BUILD_IMAGE"
+ ls -l $BUILD_IMAGE/*${MACHINE}* | sed "s#$BUILD_IMAGE/##g"
+fi
+
diff --git a/machine/quanta/quanta_come/busybox/conf/config b/machine/quanta/quanta_come/busybox/conf/config
new file mode 100644
index 00000000..623ca6ea
--- /dev/null
+++ b/machine/quanta/quanta_come/busybox/conf/config
@@ -0,0 +1,7 @@
+CONFIG_SYS_EEPROM=y
+CONFIG_SYS_EEPROM_DEVICE_I2C=y
+CONFIG_SYS_EEPROM_MAX_SIZE=256
+CONFIG_SYS_EEPROM_OFFSET=0
+CONFIG_SYS_EEPROM_SIZE=256
+CONFIG_SYS_EEPROM_I2C_DEVICE="/dev/i2c-1"
+CONFIG_SYS_EEPROM_I2C_ADDR=0x54
diff --git a/machine/quanta/quanta_come/busybox/patches/onie-sys-eeprom-come-platform.patch b/machine/quanta/quanta_come/busybox/patches/onie-sys-eeprom-come-platform.patch
new file mode 100644
index 00000000..f7025c54
--- /dev/null
+++ b/machine/quanta/quanta_come/busybox/patches/onie-sys-eeprom-come-platform.patch
@@ -0,0 +1,656 @@
+Add support for quanta_come
+
+diff --git a/include/applets.src.h b/include/applets.src.h
+index 71b8cbd..736a31b 100644
+--- a/include/applets.src.h
++++ b/include/applets.src.h
+@@ -345,6 +345,8 @@ IF_WHOAMI(APPLET_NOFORK(whoami, whoami, BB_DIR_USR_BIN, BB_SUID_DROP, whoami))
+ IF_YES(APPLET_NOFORK(yes, yes, BB_DIR_USR_BIN, BB_SUID_DROP, yes))
+ IF_ZCIP(APPLET(zcip, BB_DIR_SBIN, BB_SUID_DROP))
+ IF_SYS_EEPROM(APPLET_ODDNAME(onie-syseeprom, onie_syseeprom, BB_DIR_USR_BIN, BB_SUID_DROP, onie_syseeprom))
++APPLET_ODDNAME(mb_detect, mbdetect, BB_DIR_USR_BIN, BB_SUID_DROP, mbdetect)
++APPLET_ODDNAME(mbdetect, mbdetect, BB_DIR_USR_BIN, BB_SUID_DROP, mbdetect)
+
+ #if !defined(PROTOTYPES) && !defined(NAME_MAIN) && !defined(MAKE_USAGE) \
+ && !defined(MAKE_LINKS) && !defined(MAKE_SUID)
+diff --git a/include/i2c-dev.h b/include/i2c-dev.h
+index 23f7c2c..828e198 100644
+--- a/include/i2c-dev.h
++++ b/include/i2c-dev.h
+@@ -326,5 +326,158 @@ static inline __s32 i2c_smbus_block_process_call(int file, __u8 command,
+ }
+ }
+
++static inline __s32 i2c_dev_smbus_access(__s32 file, __u8 read_write, __u8 command,
++ __s32 size, union i2c_smbus_data *data)
++{
++ struct i2c_smbus_ioctl_data args;
++
++ args.read_write = read_write;
++ args.command = command;
++ args.size = size;
++ args.data = data;
++ return ioctl(file, I2C_SMBUS, &args);
++}
++
++static inline __s32 i2c_dev_open(__s32 i2cbus)
++{
++ __s32 file;
++ char filename[20] = "";
++
++ sprintf(filename, "/dev/i2c-%d", i2cbus);
++ file = open(filename, O_RDWR);
++
++ if (file < 0)
++ printf("Error: Could not open file %s\n", filename);
++
++ return file;
++}
++
++static inline __s32 i2c_dev_read(__s32 file, __u8 *buffer, __s32 offset, __s32 length)
++{
++ __s32 i;
++ union i2c_smbus_data data;
++
++ for (i = 0; i < length; i++)
++ {
++ if (i2c_dev_smbus_access(file, I2C_SMBUS_READ, (__u8)(i + offset), I2C_SMBUS_BYTE_DATA, &data))
++ {
++ return -1;
++ }
++ else
++ {
++ buffer[i] = 0x0FF & data.byte;
++ }
++ usleep(5000);
++ }
++
++ return 0;
++}
++
++static inline __s32 i2c_dev_write(__s32 file, __u8 *buffer, __s32 offset, __s32 length)
++{
++ __s32 i;
++ union i2c_smbus_data data;
++
++ for (i = 0; i < length; i++)
++ {
++ data.byte = (__u8)buffer[i];
++ if (i2c_dev_smbus_access(file, I2C_SMBUS_WRITE, (__u8)(i + offset), I2C_SMBUS_BYTE_DATA, &data) != 0)
++ return -1;
++ usleep(5000);
++ }
++ return 0;
++}
++
++static inline __s32 i2c_dev_seek(__s32 file, __s32 offset)
++{
++ return i2c_dev_smbus_access(file, I2C_SMBUS_WRITE, offset, I2C_SMBUS_BYTE, NULL);
++}
++
++static inline __s32 i2c_read(__s32 bus, __u8 dev, uint addr, __u8 *data, __s32 length)
++{
++ __s32 fd, ret;
++
++ fd = i2c_dev_open(bus);
++ if(fd < 0) {
++ return -1;
++ }
++
++ ret = ioctl(fd, I2C_SLAVE, dev);
++ if(ret < 0) {
++ close(fd);
++ return -1;
++ }
++
++ ret = i2c_dev_read(fd, data, addr, length);
++ if(ret < 0) {
++ close(fd);
++ return -1;
++ }
++
++ close(fd);
++ return 0;
++}
++
++static inline __s32 i2c_write(__s32 bus, __u8 dev, uint addr, __s32 alen, __u8 *data, __s32 length)
++{
++ __s32 fd, ret;
++
++ fd = i2c_dev_open(bus);
++ if(fd < 0) {
++ return -1;
++ }
++
++ ret = ioctl(fd, I2C_SLAVE, dev);
++ if(ret < 0) {
++ close(fd);
++ return -1;
++ }
++
++ ret = i2c_dev_seek(fd, addr);
++ if(ret < 0) {
++ close(fd);
++ return -1;
++ }
++
++ ret = i2c_dev_write(fd, data, alen, length);
++ if(ret < 0) {
++ close(fd);
++ return -1;
++ }
++
++ close(fd);
++ return 0;
++}
++
++/**
++ * i2c_mux_select - select channel for i2c mux
++ * 0xff will release i2c mux
++ */
++static inline __s32 i2c_mux_select(__s32 bus, __u8 chip, __u8 channel)
++{
++ __u8 data = 0;
++ if(channel == 0xff)
++ {
++ data = 0;
++ }
++ else if(channel >=0 && channel <8)
++ {
++ data = (0x01 << channel);
++ }
++ else
++ {
++ return -1;
++ }
++
++ return i2c_write(bus, chip, 0, 1, &data, 1);
++}
++
++/**
++ * i2c_mux_release - release channel for i2c mux
++ */
++static inline __s32 i2c_mux_release(__s32 bus, __u8 chip)
++{
++ return i2c_mux_select(bus, chip, 0xff);
++}
+
+ #endif /* _LINUX_I2C_DEV_H */
+diff --git a/include/mb_detect.h b/include/mb_detect.h
+new file mode 100644
+index 0000000..f0c6191
+--- /dev/null
++++ b/include/mb_detect.h
+@@ -0,0 +1,54 @@
++#ifndef __MB_DETECT_H
++#define __MB_DETECT_H
++
++typedef __u8 u8;
++typedef __u32 u32;
++typedef __s32 s32;
++
++#define MB_DETECT_I2C_BUS 1
++
++#define MAX_NUM_MB 0x3f
++#define CPU_BOARD_CAPABILITY "ixa,ixae"
++enum {
++ MB_IXA = 0,
++ MB_IXAE,
++ MB_IXAG,
++ MB_IXAEG,
++ MB_IXAA,
++ MB_IXAEA,
++ MB_LAST
++};
++
++#define I2C_DEVICE_PCA9554_LENGTH 1
++#define I2C_DEVICE_PCA9555_LENGTH 2
++typedef const struct {
++ u8 i2c_mux;
++ u8 i2c_mux_channel;
++ u8 i2c_dev;
++ u8 i2c_dev_type_length;
++ u8 i2c_dev_byte;
++ u8 i2c_dev_offset;
++} MBDetectPath;
++
++#define SYS_PRODUCT_NAME_SIZE 15 /* max. product name size */
++#define SYS_MODEL_NAME_SIZE 15 /* max. model name size */
++typedef struct {
++ u8 motherboard_id;
++ u8 projectName[SYS_PRODUCT_NAME_SIZE+1];
++ u8 productName[SYS_PRODUCT_NAME_SIZE+1];
++ u8 modelName[SYS_MODEL_NAME_SIZE+1];
++ u32 softwareVersion;
++} SysBoardInfo;
++
++typedef struct {
++ u8 i2c_mux;
++ u8 i2c_channel;
++ u8 i2c_dev;
++} SysEEPROMPath;
++
++extern u8 mb_id_get(void);
++extern u8 mb_index_get(void);
++extern s32 sys_eeprom_path_get(SysEEPROMPath *ep);
++extern s32 sys_board_info_get(SysBoardInfo *bdinfo);
++
++#endif /* __MB_DETECT_H */
+diff --git a/miscutils/Kbuild.src b/miscutils/Kbuild.src
+index 72ddcd1..7f9c2b4 100644
+--- a/miscutils/Kbuild.src
++++ b/miscutils/Kbuild.src
+@@ -56,3 +56,4 @@ lib-$(CONFIG_SYS_EEPROM_DEVICE_I2C) += sys_eeprom_i2c.o 24cXX.o
+ lib-$(CONFIG_SYS_EEPROM_DEVICE_MTD) += sys_eeprom_mtd.o
+ lib-$(CONFIG_SYS_EEPROM_DEVICE_DISK) += sys_eeprom_disk.o
+ lib-$(CONFIG_SYS_EEPROM_SYSFS_FILE) += sys_eeprom_sysfs_file.o
++lib-y += mb_detect.o
+diff --git a/miscutils/mb_detect.c b/miscutils/mb_detect.c
+new file mode 100644
+index 0000000..d47489e
+--- /dev/null
++++ b/miscutils/mb_detect.c
+@@ -0,0 +1,265 @@
++#include "libbb.h"
++#include <i2c-dev.h>
++#include <getopt.h>
++#include <mb_detect.h>
++
++extern void mbdetect_usage(void);
++
++MBDetectPath mbDetectPath[] = {
++ { 0x72, 3, 0x74, I2C_DEVICE_PCA9555_LENGTH, 1, 2 },
++};
++
++SysBoardInfo sysBoardInfo[MAX_NUM_MB] = {
++ { 0x29, "ixa_come", "IXA\0", "IXA-COME\0", 0x0000ca0b },
++ { 0x2B, "ixae_come", "IXAE\0", "IXAE-COME\0", 0x0000caeb },
++ { 0x35, "ixa_come", "IXA\0", "IXA-COME\0", 0x0000ca0b },
++ { 0x37, "ixae_come", "IXAE\0", "IXAE-COME\0", 0x0000caeb },
++};
++
++SysEEPROMPath sysEEPROMPath[] = {
++ { 0x72, 2, 0x54},
++};
++
++/*
++ * This macro defines the mbdetect command line command.
++ */
++//usage:#define mbdetect_trivial_usage
++//usage: "[-ifpdmbsce]"
++//usage:#define mbdetect_full_usage "\n\n"
++//usage: "Display Quanta Switch Motherboard detect result.\n"
++//usage: "\n -i Output motherboard id."
++//usage: "\n -f Output motherboard platform."
++//usage: "\n -p Output motherboard project."
++//usage: "\n -d Output motherboard product."
++//usage: "\n -m Output motherboard model."
++//usage: "\n -b Output eeprom i2c bus."
++//usage: "\n -s Output eeprom channel-selector address."
++//usage: "\n -c Output eeprom channel-selector channel."
++//usage: "\n -e Output eeprom slave address."
++
++void mbdetect_usage(void)
++{
++ static const char *usage =
++ "Display Quanta Switch Motherboard detect result.\n"
++ "Usage: mbdetect [-h] [-i] [-f] [-p] [-d] [-m] [-b] [-s] [-c] [-e]\n"
++ " With no arguments display all motherboard information.\n"
++ " -h --help\n"
++ " Display usage\n"
++ " -i --id\n"
++ " Output motherboard id.\n"
++ " -f --platform\n"
++ " Output motherboard platform name.\n"
++ " -p --project\n"
++ " Output motherboard project name.\n"
++ " -d --product\n"
++ " Output motherboard product name.\n"
++ " -m --model\n"
++ " Output motherboard model name.\n"
++ " -b --i2c-bus\n"
++ " Output eeprom i2c bus num.\n"
++ " -s --chan-select\n"
++ " Output eeprom i2c channel-selector address.\n"
++ " -c --chan\n"
++ " Output eeprom i2c channel-selector channel.\n"
++ " -e --eeprom-slave\n"
++ " Output eeprom i2c slave address.\n";
++
++ fprintf(stderr, "%s", usage);
++ exit(1);
++}
++
++/*
++ * do_mbdetect
++ * This function implements the mbdetect command.
++ */
++int mbdetect_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
++int mbdetect_main(int argc, char **argv)
++{
++ int count = 0;
++ int c, option_index;
++ __u8 id;
++ SysBoardInfo bdinfo;
++ SysEEPROMPath ep;
++
++ const char *short_options = "hifpdmbsce";
++ const struct option long_options[] = {
++ {"help", no_argument, 0, 'h'},
++ {"id", no_argument, 0, 'i'},
++ {"platform", no_argument, 0, 'f'},
++ {"project", no_argument, 0, 'p'},
++ {"product", no_argument, 0, 'd'},
++ {"model", no_argument, 0, 'm'},
++ {"i2c-bus", no_argument, 0, 'b'},
++ {"chan-select", no_argument, 0, 's'},
++ {"chan", no_argument, 0, 'c'},
++ {"eeprom-slave",no_argument, 0, 'e'},
++ {0, 0, 0, 0},
++ };
++
++ while (TRUE) {
++ c = getopt_long(argc, argv, short_options,
++ long_options, &option_index);
++ if (c == EOF)
++ break;
++
++ count++;
++ switch (c) {
++ case 'h':
++ mbdetect_usage();
++ break;
++
++ case 'i':
++ id = mb_id_get();
++ printf("%d\n", id);
++ break;
++
++ case 'f':
++ if(sys_board_info_get(&bdinfo) == 0) {
++ printf("quanta_%s\n", bdinfo.projectName);
++ }
++ else {
++ printf("No match motherboard detected.\n");
++ }
++ break;
++
++ case 'p':
++ if(sys_board_info_get(&bdinfo) == 0) {
++ printf("%s\n", bdinfo.projectName);
++ }
++ else {
++ printf("No match motherboard detected.\n");
++ }
++ break;
++
++ case 'd':
++ if(sys_board_info_get(&bdinfo) == 0) {
++ printf("%s\n", bdinfo.productName);
++ }
++ else {
++ printf("No match motherboard detected.\n");
++ }
++ break;
++
++ case 'm':
++ if(sys_board_info_get(&bdinfo) == 0) {
++ printf("%s\n", bdinfo.modelName);
++ }
++ else {
++ printf("No match motherboard detected.\n");
++ }
++ break;
++
++ case 'b':
++ printf("0x%02x\n", MB_DETECT_I2C_BUS);
++ break;
++
++ case 's':
++ if(sys_eeprom_path_get(&ep) == 0) {
++ printf("0x%02x\n", ep.i2c_mux);
++ }
++ else {
++ printf("No match motherboard detected.\n");
++ }
++ break;
++
++ case 'c':
++ if(sys_eeprom_path_get(&ep) == 0) {
++ printf("0x%02x\n", (1<<ep.i2c_channel));
++ }
++ else {
++ printf("No match motherboard detected.\n");
++ }
++ break;
++
++ case 'e':
++ if(sys_eeprom_path_get(&ep) == 0) {
++ printf("0x%02x\n", ep.i2c_dev);
++ }
++ else {
++ printf("No match motherboard detected.\n");
++ }
++ break;
++
++ default:
++ mbdetect_usage();
++ break;
++ }
++ }
++
++ return 0;
++}
++
++u8 mb_id_get(void) {
++ static u8 id = MAX_NUM_MB;
++ MBDetectPath *path = mbDetectPath;
++ u8 data[2];
++
++ if(id != MAX_NUM_MB) {
++ return id;
++ }
++
++ for(;path->i2c_mux!=0;path++)
++ {
++#ifdef DEBUG
++ printf("i2c_mux: 0x%02x, i2c_mux_chan: %d, i2c_dev: 0x%02x\n",
++ path->i2c_mux, path->i2c_mux_channel, path->i2c_dev);
++#endif
++ if(i2c_mux_select(MB_DETECT_I2C_BUS, path->i2c_mux, path->i2c_mux_channel) == 0)
++ {
++ if(i2c_read(MB_DETECT_I2C_BUS, path->i2c_dev, 0, data, path->i2c_dev_type_length) == 0)
++ {
++ id = (data[path->i2c_dev_byte] >> path->i2c_dev_offset) & MAX_NUM_MB;
++ i2c_mux_release(MB_DETECT_I2C_BUS, path->i2c_mux);
++ break;
++ }
++ }
++ i2c_mux_release(MB_DETECT_I2C_BUS, path->i2c_mux);
++ }
++
++ return id;
++}
++
++u8 mb_index_get(void) {
++ SysBoardInfo *bdinfo = sysBoardInfo;
++ u8 index;
++ u8 motherboard_id = mb_id_get();
++
++ for(index=0;index<MB_LAST;index++) {
++ if(motherboard_id == bdinfo->motherboard_id) {
++ break;
++ }
++ bdinfo++;
++ }
++
++ return index;
++}
++
++s32 sys_board_info_get(SysBoardInfo *bdinfo) {
++ u8 index = mb_index_get();
++
++ if(index < MB_LAST) {
++ memcpy(bdinfo, &sysBoardInfo[index], sizeof(SysBoardInfo));
++ return 0;
++ }
++
++ bdinfo = NULL;
++ return -1;
++}
++
++s32 sys_eeprom_path_get(SysEEPROMPath *ep) {
++ u8 index = mb_index_get();
++
++ if(index < MB_LAST) {
++ switch(index) {
++ /* TBD : if boardinfo eeprom is not the default path for the motherboard, should add switch case here. */
++ default:
++ memcpy(ep, &sysEEPROMPath[0], sizeof(SysEEPROMPath));
++ break;
++ }
++
++ return 0;
++ }
++
++ ep = NULL;
++ return -1;
++}
+diff --git a/miscutils/onie_tlvinfo.c b/miscutils/onie_tlvinfo.c
+index 5cf6463..45af1bd 100644
+--- a/miscutils/onie_tlvinfo.c
++++ b/miscutils/onie_tlvinfo.c
+@@ -260,12 +260,18 @@ static void decode_tlv_value(tlvinfo_tlv_t * tlv, char* value)
+ case TLV_CODE_MANUF_NAME:
+ case TLV_CODE_MANUF_COUNTRY:
+ case TLV_CODE_VENDOR_NAME:
+- case TLV_CODE_DIAG_VERSION:
+ case TLV_CODE_SERVICE_TAG:
+ memcpy(value, tlv->value, tlv->length);
+ value[tlv->length] = 0;
+ break;
+- case TLV_CODE_MAC_BASE:
++
++ case TLV_CODE_DIAG_VERSION:
++ sprintf(value, "%d.%d.%d.%d (0x%02x%02x)",
++ (tlv->value[0] & 0xf0) >> 4, tlv->value[0] & 0x0f, (tlv->value[1] & 0xf0) >> 4, tlv->value[1] & 0x0f,
++ tlv-> value[2], tlv-> value[3]);
++ break;
++
++ case TLV_CODE_MAC_BASE:
+ sprintf(value, "%02X:%02X:%02X:%02X:%02X:%02X",
+ tlv->value[0], tlv->value[1], tlv->value[2],
+ tlv->value[3], tlv->value[4], tlv->value[5]);
+@@ -638,12 +644,17 @@ bool tlvinfo_add_tlv(u_int8_t * eeprom, int tcode, char * strval)
+ case TLV_CODE_MANUF_NAME:
+ case TLV_CODE_MANUF_COUNTRY:
+ case TLV_CODE_VENDOR_NAME:
+- case TLV_CODE_DIAG_VERSION:
+ case TLV_CODE_SERVICE_TAG:
+ strncpy(data, strval, MAX_TLV_VALUE_LEN);
+ new_tlv_len = min(MAX_TLV_VALUE_LEN, strlen(strval));
+ break;
+- case TLV_CODE_DEVICE_VERSION:
++
++ case TLV_CODE_DIAG_VERSION:
++ printf("ERROR: Changing diag. version is not permitted here.\n");
++ return(FALSE);
++ break;
++
++ case TLV_CODE_DEVICE_VERSION:
+ value = strtoul(strval, NULL, 0);
+ if (value >= 256) {
+ printf("ERROR: Device version must be 255 or less. Value " \
+@@ -664,12 +675,12 @@ bool tlvinfo_add_tlv(u_int8_t * eeprom, int tcode, char * strval)
+ data[1] = value & 0xFF;
+ new_tlv_len = 2;
+ break;
+- case TLV_CODE_MANUF_DATE:
+- if (set_date(data, strval) != 0) {
+- return(FALSE);
+- }
+- new_tlv_len = 19;
++
++ case TLV_CODE_MANUF_DATE:
++ printf("ERROR: Changing manufacturing date is not permitted here.\n");
++ return(FALSE);
+ break;
++
+ case TLV_CODE_MAC_BASE:
+ if (set_mac(data, strval) != 0) {
+ return(FALSE);
+diff --git a/miscutils/sys_eeprom.c b/miscutils/sys_eeprom.c
+index 3003bd6..1c92f68 100644
+--- a/miscutils/sys_eeprom.c
++++ b/miscutils/sys_eeprom.c
+@@ -1,5 +1,6 @@
+ #include "libbb.h"
+ #include "onie_tlvinfo.h"
++#include "sys_eeprom.h"
+ #include <getopt.h>
+
+ static u_int8_t eeprom[SYS_EEPROM_SIZE];
+diff --git a/miscutils/sys_eeprom_i2c.c b/miscutils/sys_eeprom_i2c.c
+index ed3235b..97a4a4b 100644
+--- a/miscutils/sys_eeprom_i2c.c
++++ b/miscutils/sys_eeprom_i2c.c
+@@ -2,6 +2,8 @@
+ #include "onie_tlvinfo.h"
+ #include "sys_eeprom.h"
+ #include "24cXX.h"
++#include <i2c-dev.h>
++#include <mb_detect.h>
+
+ #if SYS_EEPROM_I2C_MEM_ADDR_BITS == 8
+ #define EEPROM_TYPE EEPROM_TYPE_8BIT_ADDR
+@@ -22,6 +24,13 @@ int read_sys_eeprom(void *eeprom_data, int offset, int len)
+ u_int8_t *c;
+ int addr = SYS_EEPROM_OFFSET + offset;
+
++ SysEEPROMPath ep;
++ sys_eeprom_path_get(&ep);
++ if(i2c_mux_select(MB_DETECT_I2C_BUS, ep.i2c_mux, ep.i2c_channel) != 0) {
++ printf("ERROR: Cannot select I2C mux for eeprom\n");
++ return -1;
++ }
++
+ c = eeprom_data;
+ if (eeprom_open(SYS_EEPROM_I2C_DEVICE, SYS_EEPROM_I2C_ADDR,
+ EEPROM_TYPE, &e)) {
+@@ -33,6 +42,9 @@ int read_sys_eeprom(void *eeprom_data, int offset, int len)
+ c++; addr++;
+ }
+ eeprom_close(&e);
++
++ i2c_mux_release(MB_DETECT_I2C_BUS, ep.i2c_mux);
++
+ return ret;
+ }
+
+@@ -47,6 +59,13 @@ int write_sys_eeprom(void *eeprom_data, int len)
+ u_int8_t *c;
+ u_int16_t addr = SYS_EEPROM_OFFSET;
+
++ SysEEPROMPath ep;
++ sys_eeprom_path_get(&ep);
++ if(i2c_mux_select(MB_DETECT_I2C_BUS, ep.i2c_mux, ep.i2c_channel) != 0) {
++ printf("ERROR: Cannot select I2C mux for eeprom\n");
++ return -1;
++ }
++
+ c = eeprom_data;
+ for (i = 0; i < len; i++) {
+ if (eeprom_open(SYS_EEPROM_I2C_DEVICE, SYS_EEPROM_I2C_ADDR,
+@@ -55,9 +74,12 @@ int write_sys_eeprom(void *eeprom_data, int len)
+ return -1;
+ }
+ eeprom_write_byte(&e, addr, *c);
++ usleep(5000);
+ eeprom_close(&e);
+ c++; addr++;
+ }
+
++ i2c_mux_release(MB_DETECT_I2C_BUS, ep.i2c_mux);
++
+ return ret;
+ } \ No newline at end of file
diff --git a/machine/quanta/quanta_come/busybox/patches/series b/machine/quanta/quanta_come/busybox/patches/series
new file mode 100644
index 00000000..92797346
--- /dev/null
+++ b/machine/quanta/quanta_come/busybox/patches/series
@@ -0,0 +1 @@
+onie-sys-eeprom-come-platform.patch
diff --git a/machine/quanta/quanta_come/demo/platform.conf b/machine/quanta/quanta_come/demo/platform.conf
new file mode 100644
index 00000000..c2637dff
--- /dev/null
+++ b/machine/quanta/quanta_come/demo/platform.conf
@@ -0,0 +1 @@
+# quanta_come specific info
diff --git a/machine/quanta/quanta_come/installer.conf b/machine/quanta/quanta_come/installer.conf
new file mode 100644
index 00000000..98d372e1
--- /dev/null
+++ b/machine/quanta/quanta_come/installer.conf
@@ -0,0 +1,107 @@
+# Quanta COME ONIE installer configuration
+
+description="Quanta, COME"
+
+# Default ONIE block device
+install_device_platform()
+{
+ # COMe NVMe slot 1 (right side)
+ nvme_device_prefix="/sys/devices/pci0000:00/0000:00:03.3/0000:09:00.0"
+ for d in /sys/block/nvme*; do
+ if [ -e "$d/device" ]; then
+ nvme_realpath=$(realpath $d/device)
+ if [ -n "$(echo $nvme_realpath | grep $nvme_device_prefix)" ]; then
+ echo "/dev/$(basename $d)"
+ return 0
+ fi
+ fi
+ done
+
+ echo "ERROR: Unable to find NVMe SSD here."
+ return 1
+}
+
+# Local Variables:
+# mode: shell-script
+# eval: (sh-set-shell "/bin/sh" t nil)
+# End:
+
+
+post_install()
+{
+ echo "Post installation hook"
+
+ #
+ # Add platform specific hooks here.
+ #
+ # For example, set BIOS to directly
+ # boot from hard drive as onie is
+ # already installed.
+ #
+ install_diag
+ check_base_mac
+
+ return 0
+}
+
+install_diag()
+{
+ [ -f "./diag-package.tar.xz" ] && {
+ echo "Diag Package found ..."
+ tar xf ./diag-package.tar.xz -C /
+ }
+
+ onie_boot_mnt_mounted=
+ [ -d "/diag" ] && {
+ echo -n "Installing diag images ..."
+ dev=$(install_device_platform)
+ part=$(sgdisk -p $dev | grep ONIE-BOOT | awk '{printf $1}')
+ case "$dev" in
+ *nvme*)
+ mount_dev="$dev"p"$part"
+ ;;
+ *sd*)
+ mount_dev="$dev$part"
+ ;;
+ *)
+ echo "Not support to mount $dev!"
+ return 0;
+ ;;
+ esac
+ [ -z "$( df | grep $mount_dev)" ] && {
+ mount $mount_dev $onie_boot_mnt
+ onie_boot_mnt_mounted=yes
+ }
+
+ cp -rf /diag/boot/* $onie_boot_mnt/onie
+ cp -f /diag/boot/grub/grub-diag.cfg $onie_boot_mnt/onie/grub/
+ mkdir -p $onie_boot_mnt/diag
+ cp -rf /diag/packages/*img $onie_boot_mnt/diag/
+ cp -rf /diag/conf $onie_boot_mnt/
+
+ echo -n "Installing diag grub menu ..."
+ cat <<EOF >> $onie_root_dir/grub.d/50_onie_grub
+
+# add Quanta Diag. to all ONIE boot modes
+cat \$onie_root_dir/grub/grub-diag.cfg >> \$grub_cfg
+
+EOF
+ cat /diag/boot/grub/grub-diag.cfg >> $onie_boot_mnt/grub/grub.cfg
+ cp -f /diag/boot/grub/grubenv $onie_boot_mnt/grub/
+
+ [ "$onie_boot_mnt_mounted" == "yes" ] && umount $onie_boot_mnt &> /dev/null
+ echo "done."
+ }
+}
+
+check_base_mac()
+{
+ onie-syseeprom -g 0x24 &> /dev/null || {
+ echo "Create default mac address 00:c0:9f:01:02:03"
+ onie-syseeprom -s 0x24="00:c0:9f:01:02:03" &> /dev/null
+ }
+}
+
+# Set install callback hooks
+post_install_hook=post_install
+
diff --git a/machine/quanta/quanta_come/installer/install-platform b/machine/quanta/quanta_come/installer/install-platform
new file mode 100644
index 00000000..27f6ec5e
--- /dev/null
+++ b/machine/quanta/quanta_come/installer/install-platform
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# Overrides install.sh
+check_machine_image()
+{
+ platform=$(/usr/bin/mb_detect -p)
+ image_platform_machine=$(echo $image_build_machine | sed "s/come/${platform}/g")
+ echo "ONIE: Platform Machine: $image_platform_machine"
+
+ if [ "$onie_build_machine" != "$image_build_machine" ] && [ "$onie_build_machine" != "$image_platform_machine" ] ; then
+ fail=yes
+ fi
+ if [ "$onie_machine_rev" != "$image_machine_rev" ] ; then
+ fail=yes
+ fi
+ if [ "$onie_arch" != "$image_arch" ] ; then
+ fail=yes
+ fi
+}
+
diff --git a/machine/quanta/quanta_come/kernel/config b/machine/quanta/quanta_come/kernel/config
new file mode 100644
index 00000000..0ccdc42b
--- /dev/null
+++ b/machine/quanta/quanta_come/kernel/config
@@ -0,0 +1,30 @@
+CONFIG_ACPI_IPMI=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_NVME=y
+CONFIG_I2C_I801=y
+CONFIG_USB_HID=y
+CONFIG_HID_CP2112=y
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_BETOP_FF is not set
+# CONFIG_HID_ELO is not set
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PENMOUNT is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+# CONFIG_IGB is not set
+CONFIG_IPMI_HANDLER=y
+CONFIG_IPMI_PANIC_EVENT=y
+CONFIG_IPMI_PANIC_STRING=y
+CONFIG_IPMI_DEVICE_INTERFACE=y
+CONFIG_IPMI_SI=y
+CONFIG_IPMI_SI_PROBE_DEFAULTS=y
+# CONFIG_IPMI_SSIF is not set
+CONFIG_IPMI_WATCHDOG=y
+CONFIG_IPMI_POWEROFF=y
+# CONFIG_SENSORS_IBMAEM is not set
+# CONFIG_SENSORS_IBMPEX is not set
+
diff --git a/machine/quanta/quanta_come/kernel/drivers-hid-hid_quirks.patch b/machine/quanta/quanta_come/kernel/drivers-hid-hid_quirks.patch
new file mode 100644
index 00000000..c15cadca
--- /dev/null
+++ b/machine/quanta/quanta_come/kernel/drivers-hid-hid_quirks.patch
@@ -0,0 +1,12 @@
+diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
+index 4696895..78a856d 100644
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -141,6 +141,7 @@ static const struct hid_blacklist {
+ { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD, HID_QUIRK_NO_INIT_REPORTS },
+ { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103, HID_QUIRK_NO_INIT_REPORTS },
+ { USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096, HID_QUIRK_NO_INIT_INPUT_REPORTS },
++ { USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112, HID_QUIRK_NO_INIT_REPORTS },
+
+ { 0, 0 }
+ };
diff --git a/machine/quanta/quanta_come/kernel/series b/machine/quanta/quanta_come/kernel/series
new file mode 100644
index 00000000..a276c1a5
--- /dev/null
+++ b/machine/quanta/quanta_come/kernel/series
@@ -0,0 +1 @@
+drivers-hid-hid_quirks.patch
diff --git a/machine/quanta/quanta_come/machine.make b/machine/quanta/quanta_come/machine.make
new file mode 100644
index 00000000..6fd9e9f0
--- /dev/null
+++ b/machine/quanta/quanta_come/machine.make
@@ -0,0 +1,79 @@
+#-------------------------------------------------------------------------------
+#
+# Copyright (C) 2019 Will Kuo <[email protected]>
+#
+# SPDX-License-Identifier: GPL-2.0
+#
+#-------------------------------------------------------------------------------
+#
+# Makefile fragment for Quanta COME
+#
+
+ONIE_ARCH ?= x86_64
+SWITCH_ASIC_VENDOR = bcm
+
+VENDOR_REV ?= 0
+
+# Translate hardware revision to ONIE hardware revision
+ifeq ($(VENDOR_REV),0)
+ MACHINE_REV = 0
+else
+ $(warning Unknown VENDOR_REV '$(VENDOR_REV)' for MACHINE '$(MACHINE)')
+ $(error Unknown VENDOR_REV)
+endif
+
+# The VENDOR_VERSION string is appended to the overal ONIE version
+# string. HW vendors can use this to appended their own versioning
+# information to the base ONIE version string.
+# VENDOR_VERSION = .12.34
+
+# Vendor ID -- IANA Private Enterprise Number:
+# http://www.iana.org/assignments/enterprise-numbers
+# Open Compute Project IANA number
+VENDOR_ID = 7244
+
+# Skip the i2ctools and the onie-syseeprom command for this platform
+I2CTOOLS_ENABLE = yes
+
+# The onie-syseeprom command in i2ctools is deprecated. It is recommended to
+# use the one implemented in busybox instead. The option intends to provide a
+# quick way to turn off the feature in i2ctools. The command will be removed
+# from i2ctools in the future once all machines migrate their support of
+# sys_eeprom to busybox.
+#
+# The option is significant when I2CTOOLS_ENABLE is 'yes'
+#
+I2CTOOLS_SYSEEPROM = no
+
+# Enable UEFI support
+UEFI_ENABLE = yes
+
+# Enable UEFI PXE
+PXE_EFI64_ENABLE = yes
+
+# Set the desired kernel version.
+LINUX_VERSION = 4.1
+LINUX_MINOR_VERSION = 38
+
+# Specify any extra parameters that you'd want to pass to the onie linux
+# kernel command line in EXTRA_CMDLINE_LINUX env variable. Eg:
+#
+EXTRA_CMDLINE_LINUX = acpi_osi=Linux
+
+#
+# Console parameters can be defined here (default values are in
+# build-config/arch/x86_64.make).
+# For example,
+#
+CONSOLE_SPEED = 115200
+CONSOLE_DEV = 0
+CONSOLE_FLAG = 0
+
+# Enable ipmitool
+IPMITOOL_ENABLE = yes
+
+#-------------------------------------------------------------------------------
+#
+# Local Variables:
+# mode: makefile-gmake
+# End:
diff --git a/machine/quanta/quanta_come/rootconf/sysroot-lib-onie/gen-config-platform b/machine/quanta/quanta_come/rootconf/sysroot-lib-onie/gen-config-platform
new file mode 100644
index 00000000..2f0bf3b5
--- /dev/null
+++ b/machine/quanta/quanta_come/rootconf/sysroot-lib-onie/gen-config-platform
@@ -0,0 +1,27 @@
+gen_live_config()
+{
+ # Delay to wait for CP2112 I2C bus probe
+ local delay=70
+ local cnt=0
+ while [ $cnt -lt $delay ] ; do
+ device=/dev/i2c-1
+ [ -e "$device" ] && break;
+ cnt=$(( $cnt + 1 ))
+ sleep 0.1
+ done
+
+ if [ -x "/usr/bin/mb_detect" ]; then
+ platform=$(/usr/bin/mb_detect -f)
+ elif [ -x "/usr/bin/mbdetect" ]; then
+ platform=$(/usr/bin/mbdetect -f)
+ fi
+
+ local live_machine="$platform"
+
+ if [ -n "$live_machine" ] ; then
+ cat<<EOF
+# Runtime ONIE Machine
+onie_machine="$live_machine"
+EOF
+ fi
+}
diff --git a/machine/quanta/quanta_come/rootconf/sysroot-lib-onie/sysinfo-platform b/machine/quanta/quanta_come/rootconf/sysroot-lib-onie/sysinfo-platform
new file mode 100644
index 00000000..25e67c04
--- /dev/null
+++ b/machine/quanta/quanta_come/rootconf/sysroot-lib-onie/sysinfo-platform
@@ -0,0 +1,16 @@
+
+# Copyright (C) 2014 Curt Brune <[email protected]>
+#
+# SPDX-License-Identifier: GPL-2.0
+
+# Use the contents of /sys/class/net/eth0/address
+
+get_ethaddr()
+{
+ [ -r /sys/class/net/eth0/address ] && cat /sys/class/net/eth0/address
+}
+
+# Local Variables:
+# mode: shell-script
+# eval: (sh-set-shell "/bin/sh" t nil)
+# End: