Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/84159/?format=api
https://patches.dpdk.org/api/patches/84159/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/patch/1605277875-13625-14-git-send-email-juraj.linkes@pantheon.tech/", "project": { "id": 1, "url": "https://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<1605277875-13625-14-git-send-email-juraj.linkes@pantheon.tech>", "list_archive_url": "https://inbox.dpdk.org/dev/1605277875-13625-14-git-send-email-juraj.linkes@pantheon.tech", "date": "2020-11-13T14:31:14", "name": "[v12,13/14] build: add Arm SoC meson option", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "7c935d728a389a08d46df1b2219ce7ac6be965cc", "submitter": { "id": 1626, "url": "https://patches.dpdk.org/api/people/1626/?format=api", "name": "Juraj Linkeš", "email": "juraj.linkes@pantheon.tech" }, "delegate": { "id": 1, "url": "https://patches.dpdk.org/api/users/1/?format=api", "username": "tmonjalo", "first_name": "Thomas", "last_name": "Monjalon", "email": "thomas@monjalon.net" }, "mbox": "https://patches.dpdk.org/project/dpdk/patch/1605277875-13625-14-git-send-email-juraj.linkes@pantheon.tech/mbox/", "series": [ { "id": 13874, "url": "https://patches.dpdk.org/api/series/13874/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=13874", "date": "2020-11-13T14:31:01", "name": "Arm build options rework", "version": 12, "mbox": "https://patches.dpdk.org/series/13874/mbox/" } ], "comments": "https://patches.dpdk.org/api/patches/84159/comments/", "check": "success", "checks": "https://patches.dpdk.org/api/patches/84159/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@inbox.dpdk.org", "Delivered-To": "patchwork@inbox.dpdk.org", "Received": [ "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 9EF99A09E0;\n\tFri, 13 Nov 2020 15:36:08 +0100 (CET)", "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 09817C946;\n\tFri, 13 Nov 2020 15:31:53 +0100 (CET)", "from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20])\n by dpdk.org (Postfix) with ESMTP id 87022C8E6\n for <dev@dpdk.org>; Fri, 13 Nov 2020 15:31:37 +0100 (CET)", "from localhost (localhost [127.0.0.1])\n by lb.pantheon.sk (Postfix) with ESMTP id 782EEB931F;\n Fri, 13 Nov 2020 15:31:36 +0100 (CET)", "from lb.pantheon.sk ([127.0.0.1])\n by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024)\n with ESMTP id 810vqi2oDcXH; Fri, 13 Nov 2020 15:31:35 +0100 (CET)", "from service-node1.lab.pantheon.local (unknown [46.229.239.141])\n by lb.pantheon.sk (Postfix) with ESMTP id E1B57B9309;\n Fri, 13 Nov 2020 15:31:29 +0100 (CET)" ], "X-Virus-Scanned": "amavisd-new at siecit.sk", "From": "=?utf-8?q?Juraj_Linke=C5=A1?= <juraj.linkes@pantheon.tech>", "To": "bruce.richardson@intel.com, Ruifeng.Wang@arm.com,\n Honnappa.Nagarahalli@arm.com, Phil.Yang@arm.com, vcchunga@amazon.com,\n Dharmik.Thakkar@arm.com, jerinjacobk@gmail.com, hemant.agrawal@nxp.com,\n ajit.khaparde@broadcom.com, ferruh.yigit@intel.com", "Cc": "dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= <juraj.linkes@pantheon.tech>", "Date": "Fri, 13 Nov 2020 15:31:14 +0100", "Message-Id": "<1605277875-13625-14-git-send-email-juraj.linkes@pantheon.tech>", "X-Mailer": "git-send-email 2.7.4", "In-Reply-To": "<1605277875-13625-1-git-send-email-juraj.linkes@pantheon.tech>", "References": "<1605267483-13167-1-git-send-email-juraj.linkes@pantheon.tech>\n <1605277875-13625-1-git-send-email-juraj.linkes@pantheon.tech>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "Subject": "[dpdk-dev] [PATCH v12 13/14] build: add Arm SoC meson option", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "Add Arm SoC configuration to Arm meson.build and add a meson option to\nenable those options for native builds. This is preferable to\nspecifying a cross file when doing aarch64 -> aarch64 builds, since the\ncross file specifies the toolchain as well.\n\nSigned-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech>\nReviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>\n---\n config/arm/arm64_armada_linux_gcc | 7 +-\n config/arm/arm64_armv8_linux_gcc | 5 +-\n config/arm/arm64_bluefield_linux_gcc | 6 +-\n config/arm/arm64_dpaa_linux_gcc | 6 +-\n config/arm/arm64_emag_linux_gcc | 5 +-\n config/arm/arm64_graviton2_linux_gcc | 6 +-\n config/arm/arm64_n1sdp_linux_gcc | 6 +-\n config/arm/arm64_octeontx2_linux_gcc | 6 +-\n config/arm/arm64_stingray_linux_gcc | 6 +-\n config/arm/arm64_thunderx2_linux_gcc | 5 +-\n config/arm/arm64_thunderxt88_linux_gcc | 5 +-\n config/arm/meson.build | 129 +++++++++++++++++-\n .../linux_gsg/cross_build_dpdk_for_arm64.rst | 80 ++++-------\n meson_options.txt | 2 +\n 14 files changed, 166 insertions(+), 108 deletions(-)", "diff": "diff --git a/config/arm/arm64_armada_linux_gcc b/config/arm/arm64_armada_linux_gcc\nindex 487cb2923..7cc40d1f4 100644\n--- a/config/arm/arm64_armada_linux_gcc\n+++ b/config/arm/arm64_armada_linux_gcc\n@@ -14,9 +14,4 @@ cpu = 'armv8-a'\n endian = 'little'\n \n [properties]\n-implementer_id = '0x56'\n-part_number = '0xd08'\n-max_lcores = 16\n-max_numa_nodes = 1\n-numa = false\n-disabled_drivers = ['bus/dpaa', 'bus/fslmc', 'common/dpaax']\n+soc = 'armada'\ndiff --git a/config/arm/arm64_armv8_linux_gcc b/config/arm/arm64_armv8_linux_gcc\nindex 5451a01da..64d44ead8 100644\n--- a/config/arm/arm64_armv8_linux_gcc\n+++ b/config/arm/arm64_armv8_linux_gcc\n@@ -14,7 +14,4 @@ endian = 'little'\n \n [properties]\n # Generate binaries that are portable across all Armv8 machines\n-implementer_id = 'generic'\n-part_number = 'generic'\n-max_lcores = 256\n-max_numa_nodes = 4\n+soc = 'generic'\ndiff --git a/config/arm/arm64_bluefield_linux_gcc b/config/arm/arm64_bluefield_linux_gcc\nindex 6bef87fbd..7b1fae8b9 100644\n--- a/config/arm/arm64_bluefield_linux_gcc\n+++ b/config/arm/arm64_bluefield_linux_gcc\n@@ -13,8 +13,4 @@ cpu = 'armv8-a'\n endian = 'little'\n \n [properties]\n-implementer_id = '0x41'\n-part_number = '0xd08'\n-max_lcores = 16\n-max_numa_nodes = 1\n-numa = false\n+soc = 'bluefield'\ndiff --git a/config/arm/arm64_dpaa_linux_gcc b/config/arm/arm64_dpaa_linux_gcc\nindex 37398c762..e52188842 100644\n--- a/config/arm/arm64_dpaa_linux_gcc\n+++ b/config/arm/arm64_dpaa_linux_gcc\n@@ -14,8 +14,4 @@ cpu = 'armv8-a'\n endian = 'little'\n \n [properties]\n-implementer_id = 'dpaa'\n-part_number = '0xd08'\n-max_lcores = 16\n-max_numa_nodes = 1\n-numa = false\n+soc = 'dpaa'\ndiff --git a/config/arm/arm64_emag_linux_gcc b/config/arm/arm64_emag_linux_gcc\nindex 7cbb05510..6c24b4bca 100644\n--- a/config/arm/arm64_emag_linux_gcc\n+++ b/config/arm/arm64_emag_linux_gcc\n@@ -13,7 +13,4 @@ cpu = 'armv8-a'\n endian = 'little'\n \n [properties]\n-implementer_id = '0x50'\n-part_number = '0x0'\n-max_lcores = 32\n-max_numa_nodes = 1\n+soc = 'emag'\ndiff --git a/config/arm/arm64_graviton2_linux_gcc b/config/arm/arm64_graviton2_linux_gcc\nindex cfe239797..bae35d6be 100644\n--- a/config/arm/arm64_graviton2_linux_gcc\n+++ b/config/arm/arm64_graviton2_linux_gcc\n@@ -13,8 +13,4 @@ cpu = 'armv8-a'\n endian = 'little'\n \n [properties]\n-implementor_id = '0x41'\n-implementor_pn = '0xd0c'\n-max_lcores = 64\n-max_numa_nodes = 1\n-numa = false\n+soc = 'graviton2'\ndiff --git a/config/arm/arm64_n1sdp_linux_gcc b/config/arm/arm64_n1sdp_linux_gcc\nindex b00f2d1ef..249ff4738 100644\n--- a/config/arm/arm64_n1sdp_linux_gcc\n+++ b/config/arm/arm64_n1sdp_linux_gcc\n@@ -13,8 +13,4 @@ cpu = 'armv8-a'\n endian = 'little'\n \n [properties]\n-implementer_id = '0x41'\n-part_number = '0xd0c'\n-max_lcores = 4\n-max_numa_nodes = 1\n-numa = false\n+soc = 'n1sdp'\ndiff --git a/config/arm/arm64_octeontx2_linux_gcc b/config/arm/arm64_octeontx2_linux_gcc\nindex 593769709..063018e8f 100644\n--- a/config/arm/arm64_octeontx2_linux_gcc\n+++ b/config/arm/arm64_octeontx2_linux_gcc\n@@ -13,8 +13,4 @@ cpu = 'armv8-a'\n endian = 'little'\n \n [properties]\n-implementer_id = '0x43'\n-part_number = '0xb2'\n-max_lcores = 36\n-max_numa_nodes = 1\n-numa = false\n+soc = 'octeontx2'\ndiff --git a/config/arm/arm64_stingray_linux_gcc b/config/arm/arm64_stingray_linux_gcc\nindex 6bef87fbd..1209a8c0b 100644\n--- a/config/arm/arm64_stingray_linux_gcc\n+++ b/config/arm/arm64_stingray_linux_gcc\n@@ -13,8 +13,4 @@ cpu = 'armv8-a'\n endian = 'little'\n \n [properties]\n-implementer_id = '0x41'\n-part_number = '0xd08'\n-max_lcores = 16\n-max_numa_nodes = 1\n-numa = false\n+soc = 'stingray'\ndiff --git a/config/arm/arm64_thunderx2_linux_gcc b/config/arm/arm64_thunderx2_linux_gcc\nindex c06dcdc2b..348650712 100644\n--- a/config/arm/arm64_thunderx2_linux_gcc\n+++ b/config/arm/arm64_thunderx2_linux_gcc\n@@ -13,7 +13,4 @@ cpu = 'armv8-a'\n endian = 'little'\n \n [properties]\n-implementer_id = '0x43'\n-part_number = '0xaf'\n-max_lcores = 256\n-max_numa_nodes = 2\n+soc = 'thunderx2'\ndiff --git a/config/arm/arm64_thunderxt88_linux_gcc b/config/arm/arm64_thunderxt88_linux_gcc\nindex 3ba1528e4..d31d0c6d8 100644\n--- a/config/arm/arm64_thunderxt88_linux_gcc\n+++ b/config/arm/arm64_thunderxt88_linux_gcc\n@@ -13,7 +13,4 @@ cpu = 'armv8-a'\n endian = 'little'\n \n [properties]\n-implementer_id = '0x43'\n-part_number = '0xa1'\n-max_lcores = 96\n-max_numa_nodes = 1\n+soc = 'thunderxt88'\ndiff --git a/config/arm/meson.build b/config/arm/meson.build\nindex 492b7e40f..1738e36c3 100644\n--- a/config/arm/meson.build\n+++ b/config/arm/meson.build\n@@ -30,7 +30,7 @@ native_machine_args = ['-mcpu=native']\n ## Part numbers are specific to Arm implementers\n # implementer specific aarch64 flags have middle priority\n # (will overwrite common flags)\n-# part number specific aarch64 flags have the highest priority\n+# part number specific aarch64 flags have higher priority\n # (will overwrite both common and implementer specific flags)\n implementer_generic = {\n \t'description': 'Generic armv8',\n@@ -180,6 +180,99 @@ implementers = {\n \t'dpaa': implementer_dpaa\n }\n \n+# soc specific aarch64 flags have the highest priority\n+# (will overwrite all other flags)\n+soc_generic = {\n+\t'description': 'Generic un-optimized build for all aarch64 machines.',\n+\t'implementer': 'generic',\n+\t'part_number': 'generic'\n+}\n+\n+soc_armada = {\n+\t'description': 'Marvell ARMADA',\n+\t'implementer': '0x56',\n+\t'part_number': '0xd08',\n+\t'numa': false,\n+\t'disabled_drivers': ['bus/dpaa', 'bus/fslmc', 'common/dpaax']\n+}\n+\n+soc_bluefield = {\n+\t'description': 'NVIDIA BlueField',\n+\t'implementer': '0x41',\n+\t'part_number': '0xd08',\n+\t'numa': false\n+}\n+\n+soc_dpaa = {\n+\t'description': 'NXP DPAA',\n+\t'implementer': 'dpaa',\n+\t'part_number': '0xd08',\n+\t'numa': false\n+}\n+\n+soc_emag = {\n+\t'description': 'Ampere eMAG',\n+\t'implementer': '0x50',\n+\t'part_number': '0x0'\n+}\n+\n+soc_graviton2 = {\n+\t'description': 'AWS Graviton2',\n+\t'implementer': '0x41',\n+\t'part_number': '0xd0c',\n+\t'numa': false\n+}\n+\n+soc_n1sdp = {\n+\t'description': 'Arm Neoverse N1SDP',\n+\t'implementer': '0x41',\n+\t'part_number': '0xd0c',\n+\t'flags': [\n+\t\t['RTE_MAX_LCORE', 4]\n+\t],\n+\t'numa': false\n+}\n+\n+soc_octeontx2 = {\n+\t'description': 'Marvell OCTEON TX2',\n+\t'implementer': '0x43',\n+\t'part_number': '0xb2',\n+\t'numa': false\n+}\n+\n+soc_stingray = {\n+\t'description': 'Broadcom Stingray',\n+\t'implementer': '0x41',\n+\t'part_number': '0xd08',\n+\t'numa': false\n+}\n+\n+soc_thunderx2 = {\n+\t'description': 'Marvell ThunderX2 T99',\n+\t'implementer': '0x43',\n+\t'part_number': '0xaf'\n+}\n+\n+soc_thunderxt88 = {\n+\t'description': 'Marvell ThunderX T88',\n+\t'implementer': '0x43',\n+\t'part_number': '0xa1'\n+}\n+\n+socs = {\n+\t'generic': soc_generic,\n+\t'armada': soc_armada,\n+\t'bluefield': soc_bluefield,\n+\t'dpaa': soc_dpaa,\n+\t'emag': soc_emag,\n+\t'graviton2': soc_graviton2,\n+\t'n1sdp': soc_n1sdp,\n+\t'octeontx2': soc_octeontx2,\n+\t'stingray': soc_stingray,\n+\t'thunderx2': soc_thunderx2,\n+\t'thunderxt88': soc_thunderxt88\n+}\n+\n dpdk_conf.set('RTE_ARCH_ARM', 1)\n dpdk_conf.set('RTE_FORCE_INTRINSICS', 1)\n \n@@ -192,11 +285,18 @@ if dpdk_conf.get('RTE_ARCH_32')\n else\n \t# aarch64 build\n \tuse_native_machine_args = false\n+\tarm_soc = get_option('arm_soc')\n+\tsoc_config = {}\n \tif not meson.is_cross_build()\n \t\tif machine == 'generic'\n \t\t\t# generic build\n+\t\t\tif arm_soc != ''\n+\t\t\t\terror('Arm SoC is unsupported with generic build.')\n+\t\t\tendif\n \t\t\timplementer_id = 'generic'\n \t\t\tpart_number = 'generic'\n+\t\telif arm_soc != ''\n+\t\t\tsoc_config = socs.get(arm_soc, {'not_supported': true})\n \t\telse\n \t\t\t# native build\n \t\t\t# The script returns ['Implementer', 'Variant', 'Architecture',\n@@ -215,8 +315,27 @@ else\n \t\tendif\n \telse\n \t\t# cross build\n-\t\timplementer_id = meson.get_cross_property('implementer_id')\n-\t\tpart_number = meson.get_cross_property('part_number')\n+\t\tarm_soc = meson.get_cross_property('soc', '')\n+\t\tif arm_soc == ''\n+\t\t\terror('Arm SoC must be specified in the cross file.')\n+\t\tendif\n+\t\tsoc_config = socs.get(arm_soc, {'not_supported': true})\n+\tendif\n+\n+\tsoc_flags = []\n+\tif soc_config.has_key('not_supported')\n+\t\terror('SoC @0@ not supported.'.format(arm_soc))\n+\telif soc_config != {}\n+\t\timplementer_id = soc_config['implementer']\n+\t\timplementer_config = implementers[implementer_id]\n+\t\tpart_number = soc_config['part_number']\n+\t\tsoc_flags = soc_config.get('flags', [])\n+\t\tif not soc_config.get('numa', true)\n+\t\t\thas_libnuma = 0\n+\t\tendif\n+\t\tif soc_config.has_key('disabled_drivers')\n+\t\t\tdisabled_drivers += soc_config['disabled_drivers']\n+\t\tendif\n \tendif\n \n \tif implementers.has_key(implementer_id)\n@@ -242,8 +361,8 @@ else\n \t\t '(-Dmachine=generic) build.')\n \tendif\n \n-\t# use default flags with implementer flags\n-\tdpdk_flags = flags_common + implementer_config['flags'] + part_number_config.get('flags', [])\n+\t# add flags in the proper order\n+\tdpdk_flags = flags_common + implementer_config['flags'] + part_number_config.get('flags', []) + soc_flags\n \n \t# apply supported machine args\n \tmachine_args = [] # Clear previous machine args\ndiff --git a/doc/guides/linux_gsg/cross_build_dpdk_for_arm64.rst b/doc/guides/linux_gsg/cross_build_dpdk_for_arm64.rst\nindex 063661ebf..83bdb78bf 100644\n--- a/doc/guides/linux_gsg/cross_build_dpdk_for_arm64.rst\n+++ b/doc/guides/linux_gsg/cross_build_dpdk_for_arm64.rst\n@@ -100,54 +100,32 @@ command::\n \tmeson arm64-build --cross-file config/arm/arm64_armv8_linux_gcc\n \tninja -C arm64-build\n \n-Supported cross-compilation targets\n------------------------------------\n-\n-If you wish to build for a target which is not among the current cross-files,\n-you may use various combinations of implementer/part number::\n-\n- Supported implementers:\n- 'generic': Generic armv8\n- '0x41': Arm\n- '0x43': Cavium\n- '0x50': Ampere Computing\n- '0x56': Marvell ARMADA\n- 'dpaa': NXP DPAA\n-\n- Supported part_numbers for generic:\n- 'generic': valid for all armv8-a architectures (unoptimized portable build)\n-\n- Supported part_numbers for 0x41, 0x56, dpaa:\n- '0xd03': cortex-a53\n- '0xd04': cortex-a35\n- '0xd09': cortex-a73\n- '0xd0a': cortex-a75\n- '0xd0b': cortex-a76\n- '0xd0c': neoverse-n1\n-\n- Supported part_numbers for 0x43:\n- '0xa1': thunderxt88\n- '0xa2': thunderxt81\n- '0xa3': thunderxt83\n- '0xaf': thunderx2t99\n- '0xb2': octeontx2\n-\n- Supported part_numbers for 0x50:\n- '0x0': emag\n-\n-Other cross file options\n-------------------------\n-\n-There are other options you may specify in a cross file to tailor the build::\n-\n- Supported extra configuration\n- max_numa_nodes = n # will set RTE_MAX_NUMA_NODES\n- max_lcores = n # will set RTE_MAX_LCORE\n-\n- disabled_drivers = ['bus/dpaa', 'crypto'] # add disabled drivers\n- # valid values are directories (optionally with their subdirs)\n- # in the drivers directory\n-\n- numa = false # set to false to force building for a non-NUMA system\n- # if not set or set to true, the build system will build for a NUMA\n- # system only if libnuma is installed\n+Building for an aarch64 SoC on an aarch64 build machine\n+-------------------------------------------------------\n+\n+If you wish to build on an aarch64 build machine for a different aarch64 SoC,\n+you don't need a separate cross toolchain, just a different set of\n+configuration options. To build for an aarch64 SoC, use the -Darm_soc meson\n+option::\n+\n+ meson soc_build -Darm_soc=<target_soc>\n+\n+Substitute <target_soc> with one of the supported SoCs::\n+\n+ generic: Generic un-optimized build for all aarch64 machines.\n+ armada: Marvell ARMADA\n+ bluefield: NVIDIA BlueField\n+ dpaa: NXP DPAA\n+ emag: Ampere eMAG\n+ graviton2: AWS Graviton2\n+ n1sdp: Arm Neoverse N1SDP\n+ octeontx2: Marvell OCTEON TX2\n+ stingray: Broadcom Stingray\n+ thunderx2: Marvell ThunderX2 T99\n+ thunderxt88: Marvell ThunderX T88\n+\n+These SoCs are also used in cross files, e.g.::\n+\n+ [properties]\n+ # Generate binaries that are portable across all Armv8 machines\n+ soc = 'generic'\ndiff --git a/meson_options.txt b/meson_options.txt\nindex 51ea63a4c..4ad6acfb2 100644\n--- a/meson_options.txt\n+++ b/meson_options.txt\n@@ -1,5 +1,7 @@\n # Please keep these options sorted alphabetically.\n \n+option('arm_soc', type: 'string', value: '',\n+\tdescription: 'Specify if you want to build for a particular aarch64 Arm SoC when building on an aarch64 machine.')\n option('disable_drivers', type: 'string', value: '',\n \tdescription: 'Comma-separated list of drivers to explicitly disable.')\n option('drivers_install_subdir', type: 'string', value: 'dpdk/pmds-<VERSION>',\n", "prefixes": [ "v12", "13/14" ] }{ "id": 84159, "url": "