{"id":995,"date":"2023-11-20T20:32:26","date_gmt":"2023-11-20T11:32:26","guid":{"rendered":"https:\/\/pg-mana.net\/blog\/?p=995"},"modified":"2024-09-09T17:28:17","modified_gmt":"2024-09-09T08:28:17","slug":"pci_translation_offset","status":"publish","type":"post","link":"https:\/\/pg-mana.net\/blog\/pci_translation_offset\/","title":{"rendered":"PCI BAR\u306e\u5024\u3068ACPI\u306e_CRS\u95a2\u6570"},"content":{"rendered":"\n<p>\u3053\u306e\u6295\u7a3f\u306f\u3001<a href=\"https:\/\/kernelvm.connpass.com\/event\/297033\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Kernel\/VM\u63a2\u691c\u968a@\u5317\u9678 Part 6<\/a>\u3067\u767a\u8868\u3092\u884c\u3063\u305f\u300cAArch64 ThinHypervisor\u958b\u767a\u8a18\u9332\u300d\u306e\u300cPCI Base Address Register\u306f\u7d76\u5bfe\u30a2\u30c9\u30ec\u30b9\u3058\u3083\u7121\u304b\u3063\u305f\u8a71\u300d\u3092\u8a73\u3057\u304f\u8aac\u660e\u3057\u305f\u3082\u306e\u3067\u3059\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>PCI\u306e\u5404\u30c7\u30d0\u30a4\u30b9\u306b\u306f\u3001PCI Configuration Space\u3068\u3044\u3046\u3082\u306e\u304c\u3042\u3063\u3066\u3001\u305d\u3053\u306b\u306fBase Address Register(BAR)\u304c0~5\u307e\u30676\u3064\u3042\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<p>PCI\u30c7\u30d0\u30a4\u30b9\u3092\u64cd\u4f5c\u3059\u308b\u305f\u3081\u306b\u306f\u3001BAR\u306b\u8a18\u8f09\u3055\u308c\u3066\u3044\u308b\u30a2\u30c9\u30ec\u30b9\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u3001\u6700\u8fd1\u306e\u30c7\u30d0\u30a4\u30b9\u306f\u6b86\u3069MMIO(Memory Mapped I\/O)\u3068\u306a\u3063\u3066\u3044\u3066\u3001\u30e1\u30e2\u30ea\u30a2\u30c9\u30ec\u30b9\u304c\u8a18\u8f09\u3055\u308c\u3066\u3044\u307e\u3059\u3002<br>\u6700\u8fd1\u3067\u306f\u300164bit Address\u304c\u3088\u307b\u3069\u3067BAR 0\/1\u3092\u7528\u3044\u3066BAR0\u306b\u4e0b\u4f4d32bit\u3001BAR1\u306b\u4e0a\u4f4d32bit\u304c\u8a18\u8ff0\u3055\u308c\u3066\u3044\u308b\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u57fa\u672c\u7684\u306bBAR\u306b\u66f8\u304b\u308c\u3066\u3044\u308b\u30a2\u30c9\u30ec\u30b9\u304c\u305d\u306e\u307e\u307eMMIO\u306e\u30a2\u30c9\u30ec\u30b9\u306b\u306a\u308b\u3068\u601d\u3046\u306e\u3067\u3059\u304c\u3001\u307e\u308c\u306b\u3053\u308c\u304c\u76f8\u5bfe\u30a2\u30c9\u30ec\u30b9\u3067\u8a18\u8f09\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002<br>\u4eca\u56de\u306f\u3001\u305d\u306e\u30b1\u30fc\u30b9\u306b\u3064\u3044\u3066\u8ffd\u3063\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"> \u80cc\u666f<\/h2>\n\n\n\n<p>\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u3067\u5b9f\u969b\u306ePCI Bridge\u306e\u4e0b\u306b\u5bc4\u751f\u3059\u308b\u5f62\u3067VirtIO Network Device\u3092\u751f\u3084\u3059\u5b9f\u88c5\u3092\u3057\u3066\u3044\u307e\u3057\u305f\u3002<br>\u5177\u4f53\u7684\u306b\u306f\u3001PCI Configuration Space\u3092\u8d70\u67fb\u3057\u3066\u3044\u304d\u30c7\u30d0\u30a4\u30b9\u304c\u306a\u3044Bus:Device.Function\u3092\u53d6\u5f97\u3057\u3001\u5bfe\u5fdc\u3059\u308bPCI Configuration Space\u3078\u306e\u30a2\u30af\u30bb\u30b9\u3092\u30c8\u30e9\u30c3\u30d7\u3059\u308b\u3088\u3046\u306b\u3057\u3066\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u3067VirtIO Network\u7528\u306ePCI Configuration\u3092\u63d0\u4f9b\u3059\u308b\u3001\u3068\u3044\u3046\u5b9f\u88c5\u3092\u3057\u3066\u3044\u307e\u3057\u305f\u3002<br>VirtIO Network\u304c\u5b9f\u969b\u306b\u52d5\u4f5c\u3059\u308b\u305f\u3081\u306b\u306f\u3001BAR\u306b\u8a18\u8f09\u3055\u308c\u308bMMIO\u3067VirtQueue\u306e\u51e6\u7406\u306a\u3069\u3092\u3057\u306a\u3044\u3068\u3044\u3051\u306a\u3044\u306e\u3067\u3059\u304c\u3001Linux\u306f\u8d77\u52d5\u6642\u306bBase Address\u3092\u5909\u66f4\u3057\u3066\u6574\u7406\u3057\u307e\u3059\u3002\u3053\u306e\u305f\u3081BAR\u306b\u65b0\u305f\u306a\u5024\u304c\u66f8\u304d\u8fbc\u307e\u308c\u305f\u5834\u5408\u306b\u306f\u3053\u306e\u5024\u3092\u3082\u3068\u306b\u30c8\u30e9\u30c3\u30d7\u3059\u308b\u30e1\u30e2\u30ea\u30a2\u30c9\u30ec\u30b9\u3092\u5909\u66f4\u3057\u306a\u3044\u3068\u3044\u3051\u307e\u305b\u3093\u3002<br>\u4eca\u56de\u306f64bit\u30a2\u30c9\u30ec\u30b9\u306a\u306e\u3067BAR0\/BAR1\u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u306e\u3067\u3059\u304c\u3001\u304a\u304b\u3057\u306a\u6319\u52d5\u306b\u60a9\u307e\u3055\u308c\u307e\u3057\u305f\u3002<br>\u4ee5\u4e0b\u306f\u3001Linux\u3068\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u306e\u8d77\u52d5\u6642\u306e\u30b7\u30ea\u30a2\u30eb\u51fa\u529b\u306a\u306e\u3067\u3059\u304c\u3001Linux\u304c\u5272\u308a\u5f53\u3066\u305f\u3068\u4e3b\u5f35\u3059\u308b\u30a2\u30c9\u30ec\u30b9\u3068\u5b9f\u969b\u306bPCI Configuration Space\u306eBAR\u306b\u66f8\u304d\u8fbc\u307e\u308c\u308b\u5024\u304c\u7570\u306a\u308b\u306e\u3067\u3059\u3002<br>(<code>Hypervisor: <\/code>\u3068\u66f8\u304b\u308c\u3066\u3044\u308b\u884c\u306f\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u304c\u51fa\u529b\u3057\u305f\u884c\u3067\u3059\u3002)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;    1.454562] pci 0000:00:01.0: BAR 0: assigned &#91;mem 0xe000200000-0xe000200fff 64bit]\nHypervisor: BAR0: 0x200004\nHypervisor: BAR1: 0x0\nHypervisor: New Base Address: 0x200000<\/code><\/pre>\n\n\n\n<p>Linux\u306f <code>0xe000200000<\/code> \u3092\u30a2\u30b5\u30a4\u30f3\u3057\u305f\u3068\u8868\u793a\u3057\u3066\u3044\u308b\u306e\u306b\u3001\u5b9f\u969b\u306bBAR\u306b\u66f8\u304d\u8fbc\u307e\u308c\u308b\u30a2\u30c9\u30ec\u30b9\u306f\u3001 <code>0x200000<\/code> \u3068\u306a\u3063\u3066\u3044\u307e\u3059\u3002(BAR0\u306e\u4e0b\u4f4d3bit\u306f\u30d5\u30e9\u30b0\u30670x04\u306f64bit BAR\u3067\u3042\u308b\u3053\u3068\u3092\u793a\u3057\u3066\u3044\u307e\u3059\u3002)<br>\u3053\u306e\u305f\u3081\u3001\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u306f <code>0x200000<\/code> \u3092MMIO\u9818\u57df\u3068\u8a2d\u5b9a\u3057\u3066\u30a2\u30af\u30bb\u30b9\u3092\u30c8\u30e9\u30c3\u30d7\u3059\u308b\u306e\u306b\u5bfe\u3057\u3001Linux\u306f <code>0xe000200000<\/code> \u306b\u30a2\u30af\u30bb\u30b9\u3057\u306b\u884c\u304f\u306e\u3067\u30c7\u30d0\u30a4\u30b9\u306e\u5236\u5fa1\u304c\u3067\u304d\u305a\u3001\u8d77\u52d5\u306b\u5931\u6557\u3057\u307e\u3059\u3002<br>\u3069\u3046\u3057\u3066\u3053\u306e\u3088\u3046\u306a\u3053\u3068\u306b\u306a\u308b\u306e\u304b\u3001\u6319\u52d5\u3092\u8ffd\u3044\u307e\u3059\u3002<br><br>\u306a\u304a\u4eca\u56de\u4f7f\u7528\u3059\u308bLinux\u306fGNU\/Linux 5.4\u3067\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">PCI Base Address\u306e\u5272\u308a\u5f53\u3066<\/h2>\n\n\n\n<p>PCI Base Address Register\u306bMMIO\u306e\u30a2\u30c9\u30ec\u30b9\u3092\u66f8\u304d\u8fbc\u3093\u3067\u3044\u308b\u306e\u306f\u3001<code>drivers\/pci\/setup-res.c<\/code> \u306e <a href=\"https:\/\/elixir.bootlin.com\/linux\/v5.4\/source\/drivers\/pci\/setup-res.c#L25\" target=\"_blank\" rel=\"noopener\" title=\"\">pci_std_update_resource<\/a> \u3067\u884c\u3063\u3066\u3044\u307e\u3059\u3002pci_std_update_resource\u306e\u4eca\u56de\u95a2\u4fc2\u3042\u308b\u90e8\u5206\u3092\u6982\u8981\u3092\u62bd\u51fa\u3059\u308b\u3068\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static void pci_std_update_resource(struct pci_dev *dev, int resno)\n{\n\tstruct pci_bus_region region;\n\tu32 new;\n\tint reg;\n\tstruct resource *res = dev-&gt;resource + resno;\n\n\tpcibios_resource_to_bus(dev-&gt;bus, &amp;region, res);\n\tnew = region.start;\n\tnew |= res-&gt;flags &amp; ~PCI_BASE_ADDRESS_MEM_MASK;\n\n\treg = PCI_BASE_ADDRESS_0 + 4 * resno;\n\n\tpci_write_config_dword(dev, reg, new);\n\n\tif (res-&gt;flags &amp; IORESOURCE_MEM_64) {\n\t\tnew = region.start &gt;&gt; 16 &gt;&gt; 16;\n\t\tpci_write_config_dword(dev, reg + 4, new);\n\t}\n}<\/code><\/pre>\n\n\n\n<p>\u3053\u306e\u95a2\u6570\u3067\u306f\u3001 \u914d\u5217\u3068\u306a\u3063\u3066\u3044\u308b <code>dev-&gt;resource<\/code> \u306e <code>resno<\/code> \u756a\u76ee\u306e\u30a8\u30f3\u30c8\u30ea\u3092\u53d6\u308a\u51fa\u3057\u3001\u3053\u308c\u3092  <code>pcibios_resource_to_bus<\/code> \u306b\u4e0e\u3048\u3066\u3001\u8fd4\u3063\u3066\u304d\u305f <code>region.start<\/code> \u3092BAR0\/1\u306b\u66f8\u304d\u8fbc\u3093\u3067\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u6b21\u306b <a href=\"https:\/\/elixir.bootlin.com\/linux\/v5.4\/source\/drivers\/pci\/host-bridge.c#L50\" target=\"_blank\" rel=\"noopener\" title=\"\">pcibios_resource_to_bus<\/a> \u3092\u898b\u3066\u307f\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,\n\t\t\t     struct resource *res)\n{\n\tstruct pci_host_bridge *bridge = pci_find_host_bridge(bus);\n\tstruct resource_entry *window;\n\tresource_size_t offset = 0;\n\n\tresource_list_for_each_entry(window, &amp;bridge-&gt;windows) {\n\t\tif (resource_contains(window-&gt;res, res)) {\n\t\t\toffset = window-&gt;offset;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tregion-&gt;start = res-&gt;start - offset;\n\tregion-&gt;end = res-&gt;end - offset;\n}<\/code><\/pre>\n\n\n\n<p><code>region-&gt;start = res-&gt;start - offset;<\/code> \u304c\u4eca\u56de\u6ce8\u76ee\u3059\u3079\u304d\u70b9\u306a\u306e\u3067\u3059\u304c\u3001 <code>offset<\/code> \u3068\u3044\u3046\u306e\u304c\u6c17\u306b\u306a\u308a\u307e\u3059\u3002\u3053\u306e\u5024\u306f\u3001 <code>bridge-&gt;windows<\/code> \u3092\u9806\u756a\u306b\u8abf\u3079\u3066\u3044\u304d\u3001 <code>resource_contains(window-&gt;res, res)<\/code> \u304c\u771f\u3092\u8fd4\u3057\u305f\u969b\u306b\u3001 <code>window-&gt;offset<\/code> \u306e\u5024\u304c\u30bb\u30c3\u30c8\u3055\u308c\u307e\u3059\u3002 <a href=\"https:\/\/elixir.bootlin.com\/linux\/v5.4\/source\/include\/linux\/ioport.h#L218\" target=\"_blank\" rel=\"noopener\" title=\"\">resource_contains<\/a> \u306f\u3001 <code>window-&gt;res-&gt;start &lt;= res-&gt;start &amp;&amp; window-&gt;res-&gt;end &gt;= res-&gt;end<\/code> \u306e\u969b\u306b <code>true<\/code> \u3092\u8fd4\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u3055\u3066\u3001  <code>window-&gt;offset<\/code> \u306f\u3069\u3053\u3067\u30bb\u30c3\u30c8\u3055\u308c\u308b\u306e\u3067\u3057\u3087\u3046\u304b\u3002<br>\u8abf\u3079\u305f\u3068\u3053\u308d\u3001 <a href=\"https:\/\/elixir.bootlin.com\/linux\/v5.4\/source\/drivers\/acpi\/resource.c#L513\" title=\"\">acpi_dev_new_resource_entry<\/a> \u3067\u8a2d\u5b9a\u3055\u308c\u308b\u3088\u3046\u3067\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static acpi_status acpi_dev_new_resource_entry(struct resource_win *win,\n\t\t\t\t\t       struct res_proc_context *c)\n{\n\tstruct resource_entry *rentry;\n\n\trentry = resource_list_create_entry(NULL, 0);\n\tif (!rentry) {\n\t\tc-&gt;error = -ENOMEM;\n\t\treturn AE_NO_MEMORY;\n\t}\n\t*rentry-&gt;res = win-&gt;res;\n\trentry-&gt;offset = win-&gt;offset;\n\tresource_list_add_tail(rentry, c-&gt;list);\n\tc-&gt;count++;\n\treturn AE_OK;\n}<\/code><\/pre>\n\n\n\n<p><code>rentry-&gt;offset = win-&gt;offset;<\/code> \u304c\u305d\u308c\u3067\u3059\u3002\u3053\u306e\u95a2\u6570\u306f\u3001\u3059\u3050\u4e0b\u306e <a href=\"https:\/\/elixir.bootlin.com\/linux\/v5.4\/source\/drivers\/acpi\/resource.c#L530\" target=\"_blank\" rel=\"noopener\" title=\"\">acpi_dev_process_resource<\/a> \u3067\u547c\u3070\u308c\u3066\u3044\u307e\u3059\u3002 <code>acpi_dev_process_resource<\/code> \u306e\u51e6\u7406\u6982\u8981\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,\n\t\t\t\t\t     void *context)\n{\n\tstruct res_proc_context *c = context;\n\tstruct resource_win win;\n\n\tmemset(&amp;win, 0, sizeof(win));\n\n\tif (acpi_dev_resource_memory(ares, res)\n\t    || acpi_dev_resource_io(ares, res)\n\t    || acpi_dev_resource_address_space(ares, &amp;win)\n\t    || acpi_dev_resource_ext_address_space(ares, &amp;win))\n\t\treturn acpi_dev_new_resource_entry(&amp;win, c);\n\n\treturn AE_OK;\n}<\/code><\/pre>\n\n\n\n<p><code>ares<\/code> \u3092\u5404\u95a2\u6570\u306b\u6e21\u3057\u3066\u30d1\u30fc\u30b9\u304c\u6210\u529f\u3057\u305f\u3089 <code>acpi_dev_new_resource_entry<\/code> \u3092\u547c\u3073\u51fa\u3059\u3088\u3046\u3067\u3059\u3002<br>\u3053\u3053\u307e\u3067\u306e\u4e88\u60f3\u3067\u3001 <code>win-&gt;offset<\/code> \u306b\u5024\u304c\u5165\u3063\u3066\u3044\u308b\u3060\u308d\u3046\u3068\u4e88\u60f3\u3057\u3066\u3044\u308b\u306e\u3067\u3001 <code>acpi_dev_resource_address_space<\/code> \u304b <code>acpi_dev_resource_ext_address_space<\/code> \u306e\u3069\u3061\u3089\u304b\u304c <code>true<\/code> \u3092\u8fd4\u3059\u3060\u308d\u3046\u3068\u4e88\u60f3\u3057\u307e\u3059\u3002\u3068\u308a\u3042\u3048\u305a\u3001 <a href=\"https:\/\/elixir.bootlin.com\/linux\/v5.4\/source\/drivers\/acpi\/resource.c#L288\" target=\"_blank\" rel=\"noopener\" title=\"\">acpi_dev_resource_address_space<\/a> \u3092\u898b\u3066\u307f\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bool acpi_dev_resource_address_space(struct acpi_resource *ares,\n\t\t\t\t     struct resource_win *win)\n{\n\tstruct acpi_resource_address64 addr;\n\n\twin-&gt;res.flags = 0;\n\tif (ACPI_FAILURE(acpi_resource_to_address64(ares, &amp;addr)))\n\t\treturn false;\n\n\treturn acpi_decode_space(win, (struct acpi_resource_address *)&amp;addr,\n\t\t\t\t &amp;addr.address);\n}<\/code><\/pre>\n\n\n\n<p><code>win<\/code> \u3078\u306e\u5024\u306e\u683c\u7d0d\u306f <code>acpi_decode_space<\/code> \u3067\u3084\u3063\u3066\u3044\u308b\u3088\u3046\u3067\u3059\u3002 <code>acpi_dev_resource_ext_address_space<\/code> \u3082 <code>acpi_decode_space<\/code> \u3092\u547c\u3073\u51fa\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<p><a href=\"https:\/\/elixir.bootlin.com\/linux\/v5.4\/source\/drivers\/acpi\/resource.c#L205\" target=\"_blank\" rel=\"noopener\" title=\"\">acpi_decode_space<\/a> \u306e\u3046\u3061 <code>win-&gt;offset<\/code> \u306b\u95a2\u308f\u308b\u90e8\u5206\u3092\u629c\u7c8b\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static bool acpi_decode_space(struct resource_win *win,\n\t\t\t      struct acpi_resource_address *addr,\n\t\t\t      struct acpi_address64_attribute *attr)\n{\n\t\/\/ ...\n\t\/*\n\t * For bridges that translate addresses across the bridge,\n\t * translation_offset is the offset that must be added to the\n\t * address on the secondary side to obtain the address on the\n\t * primary side. Non-bridge devices must list 0 for all Address\n\t * Translation offset bits.\n\t *\/\n\tif (addr-&gt;producer_consumer == ACPI_PRODUCER)\n\t\toffset = attr-&gt;translation_offset;\n\twin-&gt;offset = offset;\n\t\/\/ ...\n}<\/code><\/pre>\n\n\n\n<p>\u30b3\u30e1\u30f3\u30c8\u3067\u3001translate addresses\u306b\u3064\u3044\u3066\u66f8\u3044\u3066\u304a\u308a\u3001PCI\u30d6\u30ea\u30c3\u30b8\u3092\u8de8\u3050\u969b\u306b\u30a2\u30c9\u30ec\u30b9\u5909\u63db\u3092\u884c\u3046\u30d6\u30ea\u30c3\u30b8\u306f <code>attr-&gt;translation_offset<\/code> \u304c\u30bb\u30c3\u30c8\u3055\u308c\u3066\u3044\u308b\u3088\u3046\u3067\u3059\u3002<br>\u3053\u3053\u304b\u3089\u3001VirtIO Network Device\u304c\u5bc4\u751f\u3057\u3066\u3044\u305fPCI Host Bridge\u306f\u3053\u306e <code>translation_offset<\/code> \u304c\u30bb\u30c3\u30c8\u3055\u308c\u3066\u3044\u308b\u3068\u4e88\u60f3\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u3055\u3066 <code>acpi_dev_process_resource<\/code> \u306f\u3069\u3053\u304b\u3089\u547c\u3070\u308c\u3066\u3044\u308b\u306e\u3067\u3057\u3087\u3046\u304b\u3002<br>\u547c\u3073\u51fa\u3057\u4e00\u89a7\u3092\u898b\u308b\u3068\u3001 <a href=\"https:\/\/elixir.bootlin.com\/linux\/v5.4\/source\/drivers\/acpi\/resource.c#L569\" target=\"_blank\" rel=\"noopener\" title=\"\">__acpi_dev_get_resources<\/a> \u304b\u3089\u547c\u3073\u51fa\u3055\u308c\u3066\u3044\u308b\u6c17\u304c\u3057\u307e\u3059\u3002<br>\u3053\u306e\u95a2\u6570\u306f\u3001<a href=\"https:\/\/elixir.bootlin.com\/linux\/v5.4\/source\/drivers\/acpi\/resource.c#L622\" target=\"_blank\" rel=\"noopener\" title=\"\">acpi_dev_get_resources<\/a> \u306e\u5185\u90e8\u95a2\u6570\u3067\u3059\u3002 <code>__acpi_dev_get_resources<\/code> \u306e\u629c\u7c8b\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static int __acpi_dev_get_resources(struct acpi_device *adev,\n\t\t\t\t    struct list_head *list,\n\t\t\t\t    int (*preproc)(struct acpi_resource *, void *),\n\t\t\t\t    void *preproc_data, char *method)\n{\n\tstruct res_proc_context c;\n\tacpi_status status;\n\n\tc.list = list;\n\tc.preproc = preproc;\n\tc.preproc_data = preproc_data;\n\tc.count = 0;\n\tc.error = 0;\n\tstatus = acpi_walk_resources(adev-&gt;handle, method,\n\t\t\t\t     acpi_dev_process_resource, &amp;c);\n\n\treturn c.count;\n}<\/code><\/pre>\n\n\n\n<p><code>acpi_dev_process_resource<\/code> \u306f <code>acpi_walk_resources<\/code> \u306e\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u95a2\u6570\u3068\u3057\u3066\u6e21\u3055\u308c\u3066\u3044\u307e\u3059\u3002 <a href=\"https:\/\/elixir.bootlin.com\/linux\/v5.4\/source\/drivers\/acpi\/acpica\/rsxface.c#L593\" target=\"_blank\" rel=\"noopener\" title=\"\">acpi_walk_resources<\/a> \u306f ACPICA\u306e\u95a2\u6570\u3067\u3001\u30ea\u30bd\u30fc\u30b9\u306e\u30ea\u30b9\u30c8\u304b\u3089\u4e00\u3064\u305a\u3064\u30a8\u30f3\u30c8\u30ea\u3092\u53d6\u308a\u51fa\u3057\u3066\u3001\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u95a2\u6570\u3092\u547c\u3073\u51fa\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<p><code>acpi_dev_get_resources<\/code> \u306e\u30b3\u30e1\u30f3\u30c8\u306b\u306f\u3001 &#8220;Evaluate the _CRS method for the given device node and process its output&#8221;\u3068\u3042\u308a\u3001\u6e21\u3055\u308c\u305f\u30c7\u30d0\u30a4\u30b9\u306e_CRS\u95a2\u6570\u3092\u8a55\u4fa1\u3059\u308b\u3088\u3046\u3067\u3059\u3002<\/p>\n\n\n\n<p>\u3053\u306e\u95a2\u6570\u3092\u547c\u3073\u51fa\u3057\u3066\u3044\u305d\u3046\u306a\u306e\u306f\u3001 <a href=\"https:\/\/elixir.bootlin.com\/linux\/v5.4\/source\/drivers\/acpi\/pci_root.c#L769\" target=\"_blank\" rel=\"noopener\" title=\"\">acpi_pci_probe_root_resources<\/a> \u3060\u3068\u4e88\u60f3\u3057\u307e\u3059\u3002<br>\u3053\u308c\u306b\u95a2\u3057\u3066\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u304c\u3001 <a href=\"https:\/\/docs.kernel.org\/PCI\/acpi-info.html\" target=\"_blank\" rel=\"noopener\" title=\"\">https:\/\/docs.kernel.org\/PCI\/acpi-info.html<\/a> \u306b\u5b58\u5728\u3057\u307e\u3059\u3002<br>\u3053\u3053\u304b\u3089\u5fc5\u8981\u306a\u90e8\u5206\u3092\u8aad\u307f\u53d6\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u307e\u305a\u3001&#8221;For example, there&#8217;s no standard hardware mechanism for enumerating PCI host bridges, so the ACPI namespace must describe each host bridge, the method for accessing PCI config space below it, the address space windows the host bridge forwards to PCI (using _CRS), and the routing of legacy INTx interrupts (using _PRT).&#8221;\u3068\u3044\u3046\u8a18\u8ff0\u306b\u6ce8\u76ee\u3057\u307e\u3059\u3002\u8981\u7d04\u3059\u308b\u3068\u3001\u300cPCI host bridge\u3092\u691c\u51fa\u3059\u308b\u6a19\u6e96\u7684\u306a\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u30e1\u30ab\u30cb\u30ba\u30e0\u306f\u5b58\u5728\u305b\u305a\u3001ACPI\u540d\u524d\u7a7a\u9593\u306b\u304a\u3044\u3066_CRS\u3092\u8a55\u4fa1\u3059\u308b\u3053\u3068\u3067\u30a2\u30c9\u30ec\u30b9\u7a7a\u9593\u306e\u60c5\u5831\u3092\u53d6\u5f97\u3067\u304d\u308b\u3002\u300d\u3068\u3044\u3046\u611f\u3058\u3067\u3057\u3087\u3046\u304b\u3002<br>PCI Configuration Space\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u65b9\u6cd5\u3068\u3057\u3066\u3001ECAM\u304c\u3042\u308a\u3001\u3053\u308c\u306fMCFG\u30c6\u30fc\u30d6\u30eb\u3092\u8aad\u307f\u53d6\u308b\u3053\u3068\u3067\u30a2\u30af\u30bb\u30b9\u53ef\u80fd\u3060\u3068\u7406\u89e3\u3057\u3066\u307e\u3057\u305f\u3002\u3053\u308c\u306b\u3064\u3044\u3066\u306f\u3001&#8221;Static tables like MCFG, HPET, ECDT, etc., are not mechanisms for reserving address space. The static tables are for things the OS needs to know early in boot, before it can parse the ACPI namespace. &#8220;\u3068\u3042\u308a\u3001MCFG\u306a\u3069\u306e\u9759\u7684\u30c6\u30fc\u30d6\u30eb\u306f\u3042\u304f\u307e\u3067\u8d77\u52d5\u521d\u671f\u306b\u66ab\u5b9a\u7684\u306b\u4f7f\u7528\u3059\u308b\u4e8b\u3092\u76ee\u7684\u3068\u3057\u3066\u3044\u308b\u3088\u3046\u3067\u3059\u3002<br>PCI host bridge\u306b\u3064\u3044\u3066\u3001&#8221;PCI host bridges are PNP0A03 or PNP0A08 devices.&#8221;\u3068\u3042\u308a\u3001_HID\u304c\u3053\u308c\u3067\u3042\u308b\u30c7\u30d0\u30a4\u30b9\u3092\u898b\u3064\u3051\u3066\u304f\u308c\u3070\u826f\u3044\u3068\u3044\u3046\u3053\u3068\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u3055\u3066\u3001\u4eca\u56de\u4f7f\u7528\u3057\u3066\u3044\u308b\u30c7\u30d0\u30a4\u30b9\u306eDSDT\/SSDT\u3092iasl\u3067\u30c7\u30a3\u30b9\u30a2\u30bb\u30f3\u30d6\u30eb\u3057\u3001&#8221;PNP0A08&#8243;\u3092\u63a2\u3057\u3066\u307f\u305f\u7d50\u679c\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u30c7\u30d0\u30a4\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002(\u5fc5\u8981\u306a\u90e8\u5206\u306e\u307f\u629c\u7c8b)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    Scope (_SB)\n    {\n        Device (PCI0)\n        {\n            Name (_HID, EisaId (\"PNP0A08\") \/* PCI Express Bus *\/)  \/\/ _HID: Hardware ID\n            Name (_CID, EisaId (\"PNP0A03\") \/* PCI Bus *\/)  \/\/ _CID: Compatible ID\n            Name (_SEG, Zero)  \/\/ _SEG: PCI Segment\n            Name (_BBN, Zero)  \/\/ _BBN: BIOS Bus Number\n\n            Method (_CRS, 0, Serialized)  \/\/ _CRS: Current Resource Settings\n            {\n                Name (RBUF, ResourceTemplate ()\n                {\n                    WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,\n                        0x0000,             \/\/ Granularity\n                        0x0000,             \/\/ Range Minimum\n                        0x00FD,             \/\/ Range Maximum\n                        0x0000,             \/\/ Translation Offset\n                        0x00FE,             \/\/ Length\n                        ,, )\n                    QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,\n                        0x0000000000000000, \/\/ Granularity\n                        0x0000000000000000, \/\/ Range Minimum\n                        0x000000007FFFFFFF, \/\/ Range Maximum\n                        0x000000E000000000, \/\/ Translation Offset\n                        0x0000000080000000, \/\/ Length\n                        ,, , AddressRangeMemory, TypeStatic)\n                    QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Prefetchable, ReadWrite,\n                        0x0000000000000000, \/\/ Granularity\n                        0x000000E200000000, \/\/ Range Minimum\n                        0x000000FFFFFFFFFF, \/\/ Range Maximum\n                        0x0000000000000000, \/\/ Translation Offset\n                        0x0000001E00000000, \/\/ Length\n                        ,, , AddressRangeMemory, TypeStatic)\n                })\n                Return (RBUF) \/* \\_SB_.PCI0._CRS.RBUF *\/\n            }\n}<\/code><\/pre>\n\n\n\n<p>_CRS\u95a2\u6570\u3067\u306f\u30013\u3064\u306e\u30ea\u30bd\u30fc\u30b9\u304c\u8a18\u8ff0\u3055\u308c\u3066\u3044\u307e\u3059\u3002<br>_CRS\u95a2\u6570\u306e\u8fd4\u3059\u5024\u306b\u3064\u3044\u3066\u306e\u8aac\u660e\u306f\u3001<a href=\"https:\/\/uefi.org\/htmlspecs\/ACPI_Spec_6_4_html\/06_Device_Configuration\/Device_Configuration.html#resource-data-types-for-acpi\" target=\"_blank\" rel=\"noopener\" title=\"\">Device Configuration \u2014 ACPI Specification 6.4 documentation<\/a> \u306b\u3042\u308a\u307e\u3059\u3002<br><a href=\"https:\/\/uefi.org\/htmlspecs\/ACPI_Spec_6_4_html\/06_Device_Configuration\/Device_Configuration.html#qword-address-space-descriptor\" target=\"_blank\" rel=\"noopener\" title=\"\">QWordMemory<\/a> \u306e\u9805\u3092\u898b\u308b\u3068\u3001&#8221;Address Translation offset&#8221;\u3068\u3044\u3046\u3082\u306e\u304c\u3042\u308a\u3001_CRS\u306e\u8fd4\u3059\u30a8\u30f3\u30c8\u30ea\u306e2\u756a\u76ee\u3092\u898b\u308b\u3068\u3001&#8221;0x000000E000000000, \/\/ Translation Offset&#8221;\u3068\u3042\u308a\u3001\u3053\u308c\u304c\u5de1\u308a\u5de1\u3063\u3066\u3001 <code>offset<\/code> \u306e\u5024\u306b\u306a\u3063\u3066\u3044\u308b\u3068\u8003\u3048\u308b\u3068\u4e0d\u53ef\u89e3\u306a\u6319\u52d5\u3082\u7d0d\u5f97\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u691c\u8a3c<\/h2>\n\n\n\n<p>\u4eca\u307e\u3067\u306e\u30b3\u30fc\u30c9\u30ea\u30fc\u30c7\u30a3\u30f3\u30b0\u3067\u7acb\u3066\u305f\u4eee\u8aac\u3092\u691c\u8a3c\u3059\u308b\u305f\u3081\u306bLinux Kernel\u306b <code>pr_info<\/code> \u3092\u52a0\u3048\u3066\u5024\u306e\u78ba\u8a8d\u3092\u3057\u3066\u307f\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u307e\u305a\u306f\u3001 <code>pci_std_update_resource<\/code> \u3092\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u66f8\u304d\u63db\u3048\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        pr_info(\"%s: res-&gt;start = 0x%llx\\n\", __func__, res-&gt;start);\n        pcibios_resource_to_bus(dev-&gt;bus, &amp;region, res);\n        pr_info(\"%s: region.start = 0x%llx\\n\", __func__, region.start);\n        new = region.start;<\/code><\/pre>\n\n\n\n<p>\u6b21\u306b\u3001 <code>pcibios_resource_to_bus<\/code> \u3092\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u66f8\u304d\u63db\u3048\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        resource_list_for_each_entry(window, &amp;bridge-&gt;windows) {\n                if (resource_contains(window-&gt;res, res)) {\n                        pr_info(\"%s: window-&gt;offset: 0x%llx\\n\", __func__, window-&gt;offset);\n                        offset = window-&gt;offset;\n                        break;\n                }\n        }<\/code><\/pre>\n\n\n\n<p>\u66f4\u306b\u3001 <code>acpi_dev_new_resource_entry<\/code> \u306b\u3082 <code>pr_info<\/code> \u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        *rentry-&gt;res = win-&gt;res;\n        pr_info(\"%s: win-&gt;offset: 0x%llx\\n\", __func__, win-&gt;offset);\n        rentry-&gt;offset = win-&gt;offset;<\/code><\/pre>\n\n\n\n<p><code>acpi_dev_resource_address_space<\/code> \u304b <code>acpi_dev_resource_ext_address_space<\/code> \u306b\u3082\u547c\u3070\u308c\u305f\u75d5\u8de1\u304c\u6b8b\u308b\u3088\u3046\u306b\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bool acpi_dev_resource_address_space(struct acpi_resource *ares,\n\t\t\t\t     struct resource_win *win)\n{\n\tstruct acpi_resource_address64 addr;\n\n\twin-&gt;res.flags = 0;\n\tif (ACPI_FAILURE(acpi_resource_to_address64(ares, &amp;addr)))\n\t\treturn false;\n        pr_info(\"%s: Called\\n\", __func__);\n\treturn acpi_decode_space(win, (struct acpi_resource_address *)&amp;addr,\n}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,\n                                         struct resource_win *win)\n{\n        struct acpi_resource_extended_address64 *ext_addr;\n\n        win-&gt;res.flags = 0;\n        if (ares-&gt;type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)\n                return false;\n\n        ext_addr = &amp;ares-&gt;data.ext_address64;\n        pr_info(\"%s: Called\\n\", __func__);\n        return acpi_decode_space(win, (struct acpi_resource_address *)ext_addr,\n                                 &amp;ext_addr-&gt;address);\n}<\/code><\/pre>\n\n\n\n<p>\u6700\u5f8c\u306b\u3001 <code>acpi_pci_probe_root_resources<\/code> \u3082\u4e88\u60f3\u3057\u305f\u30c7\u30d0\u30a4\u30b9\u304c\u8a55\u4fa1\u3055\u308c\u3066\u3044\u308b\u304b\u8868\u793a\u3059\u308b\u3088\u3046\u306b\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)\n{\n        int ret;\n        struct list_head *list = &amp;info-&gt;resources;\n        struct acpi_device *device = info-&gt;bridge;\n        struct resource_entry *entry, *tmp;\n        unsigned long flags;\n\n        flags = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT;\n        pr_info(\"%s: probe %s\\n\", __func__, info-&gt;name);\n        \/\/ ...\n}<\/code><\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5909\u66f4\u3092\u9069\u7528\u3057\u305fLinux Kernel\u3092\u30d3\u30eb\u30c9\u3057\u3066\u5dee\u3057\u66ff\u3048\u3066\u8d77\u52d5\u3057\u3066\u307f\u307e\u3059\u3002<br>\u307e\u305a\u306f\u3001PCI Root Bus\u3092\u8a8d\u8b58\u3057\u3066\u3044\u308b\u4ed8\u8fd1\u306eBoot Message\u3092\u898b\u3066\u307f\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;   24.084991] acpi PNP0A08:00: ECAM area &#91;mem 0xe100000000-0xe10fdfffff] reserved by PNP0C02:00\n&#91;   24.093530] acpi PNP0A08:00: ECAM at &#91;mem 0xe100000000-0xe10fdfffff] for &#91;bus 00-fd]\n&#91;   24.101266] acpi_pci_probe_root_resources: probe PCI Bus 0000:00\n&#91;   24.201701] acpi_dev_resource_address_space: Called\n&#91;   24.206568] acpi_dev_new_resource_entry: win-&gt;offset: 0xe000000000\n&#91;   24.212736] acpi_dev_resource_address_space: Called\n&#91;   24.217603] acpi_dev_new_resource_entry: win-&gt;offset: 0x0\n&#91;   24.223076] PCI host bridge to bus 0000:00\n&#91;   24.227166] pci_bus 0000:00: root bus resource &#91;mem 0xe000000000-0xe07fffffff window] (bus address &#91;0x00000000-0x7fffffff])\n&#91;   24.238283] pci_bus 0000:00: root bus resource &#91;mem 0xe200000000-0xffffffffff pref window]\n&#91;   24.246535] pci_bus 0000:00: root bus resource &#91;bus 00-fd]<\/code><\/pre>\n\n\n\n<p><code>acpi_pci_probe_root_resources<\/code> \u2192 <code>acpi_dev_resource_address_space<\/code> \u2192 <code>acpi_dev_new_resource_entry<\/code> \u306e\u9806\u756a\u3067\u547c\u3070\u308c\u3066\u3044\u308b\u3088\u3046\u3067\u3059\u306d\u3002Translation Offset\u306e\u5024\u304c\u53d6\u308a\u51fa\u3055\u308c\u3001resource\u304c\u4f5c\u6210\u3055\u308c\u3066\u3044\u308b\u3088\u3046\u3067\u3059\u3002<br>\u6b21\u306b\u3001\u5b9f\u969b\u306bVirtIO Network Device\u306eBAR\u306b\u5024\u304c\u66f8\u304d\u8fbc\u307e\u308c\u3066\u3044\u308b\u6240\u3092\u898b\u3066\u307f\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;   24.462843] pci 0000:00:01.0: BAR 0: assigned &#91;mem 0xe000200000-0xe000200fff 64bit]\n&#91;   24.470487] pci_std_update_resource: res-&gt;start = 0xe000200000\n&#91;   24.476308] pcibios_resource_to_bus: window-&gt;offset: 0xe000000000\n&#91;   24.482389] pci_std_update_resource: region.start = 0x200000<\/code><\/pre>\n\n\n\n<p>\u4e88\u60f3\u901a\u308a\u3001Translation Offset\u306e\u5024\u304c\u3053\u3053\u306b\u4f1d\u64ad\u3057\u3001 <code>region.start<\/code> \u306e\u5024\u304c\u5909\u66f4\u3055\u308c\u3066\u3044\u307e\u3059\u3002<br>\u691c\u8a3c\u306e\u7d50\u679c\u3001\u4e88\u60f3\u3069\u304a\u308a\u306e\u6319\u52d5\u3092\u793a\u3057\u3066\u3044\u308b\u4e8b\u3092\u78ba\u8a8d\u3067\u304d\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u7d50\u8ad6<\/h2>\n\n\n\n<p>PCI\u306eBase Address Register\u306e\u5024\u3092\u8aad\u307f\u66f8\u304d\u3059\u308b\u969b\u306fDSDT\/SSDT\u306eAML\u3092\u3088\u304f\u8aad\u3093\u3067\u3001Translation Offset\u306e\u5024\u306b\u6ce8\u610f\u3057\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u8ffd\u4f38<\/h2>\n\n\n\n<p>ACPI\u88ab\u5bb3\u8005\u306e\u4f1a\u306f\u968f\u6642\u4f1a\u54e1\u3092\u52df\u96c6\u3057\u3066\u304a\u308a\u307e\u3059\u3002<br>ACPI\u306e\u3042\u3093\u306a\u6319\u52d5\u3084\u3053\u3093\u306a\u6319\u52d5\u3067\u60a9\u307e\u3055\u308c\u305f\u65b9\u306f\u662f\u975e\u3001\u30d6\u30ed\u30b0\u8a18\u4e8b\u306a\u3069\u3067\u300cACPI\u88ab\u5bb3\u8005\u306e\u4f1a\u300d\u3068\u8a00\u3046\u30ef\u30fc\u30c9\u3068\u5171\u306b\u6295\u7a3f\u3057\u3066\u307f\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u3053\u306e\u6295\u7a3f\u306f\u3001Kernel\/VM\u63a2\u691c\u968a@\u5317\u9678 Part 6\u3067\u767a\u8868\u3092\u884c\u3063\u305f\u300cAArch64 ThinHypervisor\u958b\u767a\u8a18\u9332\u300d\u306e\u300cPCI Base Address Register\u306f\u7d76\u5bfe\u30a2\u30c9\u30ec\u30b9\u3058\u3083\u7121\u304b\u3063\u305f\u8a71\u300d\u3092\u8a73\u3057\u304f\u8aac [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-995","post","type-post","status-publish","format-standard","hentry","category-linux"],"_links":{"self":[{"href":"https:\/\/pg-mana.net\/blog\/wp-json\/wp\/v2\/posts\/995","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pg-mana.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pg-mana.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pg-mana.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pg-mana.net\/blog\/wp-json\/wp\/v2\/comments?post=995"}],"version-history":[{"count":0,"href":"https:\/\/pg-mana.net\/blog\/wp-json\/wp\/v2\/posts\/995\/revisions"}],"wp:attachment":[{"href":"https:\/\/pg-mana.net\/blog\/wp-json\/wp\/v2\/media?parent=995"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pg-mana.net\/blog\/wp-json\/wp\/v2\/categories?post=995"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pg-mana.net\/blog\/wp-json\/wp\/v2\/tags?post=995"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}