blob: 7404ae586ab79d1af5dae4bfda85e5679d3c03b7 [file] [log] [blame]
Moritz Fischer058fb9f2022-02-05 12:17:45 -08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Write an ACPI MCFG table
4 *
5 * Copyright 2022 Google LLC
6 */
7
8#define LOG_CATEGORY LOGC_ACPI
9
10#include <common.h>
11#include <mapmem.h>
12#include <tables_csum.h>
13#include <acpi/acpi_table.h>
14#include <dm/acpi.h>
15
16int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base,
17 u16 seg_nr, u8 start, u8 end)
18{
19 memset(mmconfig, 0, sizeof(*mmconfig));
20 mmconfig->base_address_l = base;
21 mmconfig->base_address_h = 0;
22 mmconfig->pci_segment_group_number = seg_nr;
23 mmconfig->start_bus_number = start;
24 mmconfig->end_bus_number = end;
25
26 return sizeof(struct acpi_mcfg_mmconfig);
27}
28
29__weak int acpi_fill_mcfg(struct acpi_ctx *ctx)
30{
31 return -ENOENT;
32}
33
34/* MCFG is defined in the PCI Firmware Specification 3.0 */
35int acpi_write_mcfg(struct acpi_ctx *ctx, const struct acpi_writer *entry)
36{
37 struct acpi_table_header *header;
38 struct acpi_mcfg *mcfg;
39 int ret;
40
41 mcfg = ctx->current;
42 header = &mcfg->header;
43
44 memset(mcfg, '\0', sizeof(struct acpi_mcfg));
45
46 /* Fill out header fields */
47 acpi_fill_header(header, "MCFG");
48 header->length = sizeof(struct acpi_mcfg);
49 header->revision = 1;
50 acpi_inc(ctx, sizeof(*mcfg));
51
52 ret = acpi_fill_mcfg(ctx);
53 if (ret)
54 return log_msg_ret("fill", ret);
55
56 /* (Re)calculate length and checksum */
57 header->length = (ulong)ctx->current - (ulong)mcfg;
58 header->checksum = table_compute_checksum(mcfg, header->length);
59
60 acpi_add_table(ctx, mcfg);
61
62 return 0;
63}
64ACPI_WRITER(5mcfg, "MCFG", acpi_write_mcfg, 0);