1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
/* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpigen.h>
#include <acpi/acpigen_pci.h>
#include <device/pci_def.h>
#include <device/pci_ops.h>
#include <string.h>
#include "acpi_pirq_gen.h"
static void gen_apic_route(const struct slot_pin_irq_map *pin_irq_map,
unsigned int map_count)
{
for (unsigned int i = 0; i < map_count; i++)
/*
* The reason for subtracting PCI_INT_A from the pin given is
* that PCI defines pins as 1-4, and _PRT uses 0-3.
*/
acpigen_write_PRT_GSI_entry(pin_irq_map[i].slot,
pin_irq_map[i].pin - PCI_INT_A,
pin_irq_map[i].apic_gsi);
}
static void gen_pic_route(const struct slot_pin_irq_map *pin_irq_map,
unsigned int map_count,
const struct pic_pirq_map *pirq_map)
{
for (unsigned int i = 0; i < map_count; i++) {
enum pirq pirq = pin_irq_map[i].pic_pirq;
unsigned int pin = pin_irq_map[i].pin - PCI_INT_A;
if (pirq == PIRQ_INVALID)
continue;
if (pirq_map->type == PIRQ_GSI)
acpigen_write_PRT_GSI_entry(pin_irq_map[i].slot,
pin,
pirq_map->gsi[pirq]);
else
acpigen_write_PRT_source_entry(pin_irq_map[i].slot,
pin,
pirq_map->source_path[pirq],
0);
}
}
void intel_write_pci0_PRT(const struct slot_pin_irq_map *pin_irq_map,
unsigned int map_count,
const struct pic_pirq_map *pirq_map)
{
/* \_SB.PCI0._PRT */
acpigen_write_scope("\\_SB.PCI0");
acpigen_write_method("_PRT", 0);
acpigen_write_if();
acpigen_emit_namestring("PICM");
acpigen_emit_byte(RETURN_OP);
acpigen_write_package(map_count);
gen_apic_route(pin_irq_map, map_count);
acpigen_pop_len(); /* package */
acpigen_write_else();
acpigen_emit_byte(RETURN_OP);
acpigen_write_package(map_count);
gen_pic_route(pin_irq_map, map_count, pirq_map);
acpigen_pop_len(); /* package */
acpigen_pop_len(); /* else PICM */
acpigen_pop_len(); /* _PRT */
acpigen_pop_len(); /* \_SB */
}
bool is_slot_pin_assigned(const struct slot_pin_irq_map *pin_irq_map,
unsigned int map_count, unsigned int slot,
enum pci_pin pin)
{
for (size_t i = 0; i < map_count; i++) {
if (pin_irq_map[i].slot == slot && pin_irq_map[i].pin == pin)
return true;
}
return false;
}
|