arch/x86/pci/amd_bus.c

Source file repositories/reference/linux-study-clean/arch/x86/pci/amd_bus.c

File Facts

System
Linux kernel
Corpus path
arch/x86/pci/amd_bus.c
Extension
.c
Size
9905 bytes
Lines
413
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct amd_hostbridge {
	u32 bus;
	u32 slot;
	u32 device;
};

/*
 * IMPORTANT NOTE:
 * hb_probes[] and early_root_info_init() is in maintenance mode.
 * It only supports K8, Fam10h, Fam11h, and Fam15h_00h-0fh .
 * Future processor will rely on information in ACPI.
 */
static struct amd_hostbridge hb_probes[] __initdata = {
	{ 0, 0x18, 0x1100 }, /* K8 */
	{ 0, 0x18, 0x1200 }, /* Family10h */
	{ 0xff, 0, 0x1200 }, /* Family10h */
	{ 0, 0x18, 0x1300 }, /* Family11h */
	{ 0, 0x18, 0x1600 }, /* Family15h */
};

static struct pci_root_info __init *find_pci_root_info(int node, int link)
{
	struct pci_root_info *info;

	/* find the position */
	list_for_each_entry(info, &pci_root_infos, list)
		if (info->node == node && info->link == link)
			return info;

	return NULL;
}

static inline resource_size_t cap_resource(u64 val)
{
	if (val > RESOURCE_SIZE_MAX)
		return RESOURCE_SIZE_MAX;

	return val;
}

/**
 * early_root_info_init()
 * called before pcibios_scan_root and pci_scan_bus
 * fills the mp_bus_to_cpumask array based according
 * to the LDT Bus Number Registers found in the northbridge.
 */
static int __init early_root_info_init(void)
{
	int i;
	unsigned bus;
	unsigned slot;
	int node;
	int link;
	int def_node;
	int def_link;
	struct pci_root_info *info;
	u32 reg;
	u64 start;
	u64 end;
	struct range range[RANGE_NUM];
	u64 val;
	u32 address;
	bool found;
	struct resource fam10h_mmconf_res, *fam10h_mmconf;
	u64 fam10h_mmconf_start;
	u64 fam10h_mmconf_end;

	if (!early_pci_allowed())
		return -1;

	found = false;
	for (i = 0; i < ARRAY_SIZE(hb_probes); i++) {
		u32 id;
		u16 device;
		u16 vendor;

		bus = hb_probes[i].bus;
		slot = hb_probes[i].slot;
		id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID);
		vendor = id & 0xffff;
		device = (id>>16) & 0xffff;

		if (vendor != PCI_VENDOR_ID_AMD &&
		    vendor != PCI_VENDOR_ID_HYGON)
			continue;

		if (hb_probes[i].device == device) {
			found = true;
			break;
		}

Annotation

Implementation Notes