xref: /minix/minix/drivers/power/acpi/acpi.c (revision 83133719)
1 #include <minix/driver.h>
2 #include <acpi.h>
3 #include <assert.h>
4 #include <minix/acpi.h>
5 
6 #include "pci.h"
7 
8 int acpi_enabled;
9 struct machine machine;
10 
11 /* don't know where ACPI tables are, we may need to access any memory */
12 static int init_mem_priv(void)
13 {
14 	struct minix_mem_range mr;
15 
16 	mr.mr_base = 0;
17 	mr.mr_limit = 0xffffffff;
18 
19 	return sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mr);
20 }
21 
22 static void set_machine_mode(void)
23 {
24     ACPI_OBJECT arg1;
25     ACPI_OBJECT_LIST args;
26     ACPI_STATUS as;
27 
28     arg1.Type = ACPI_TYPE_INTEGER;
29     arg1.Integer.Value = machine.apic_enabled ? 1 : 0;
30     args.Count = 1;
31     args.Pointer = &arg1;
32 
33     as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &args, NULL);
34     /*
35      * We can silently ignore failure as it may not be implemented, ACPI should
36      * provide us with correct information anyway
37      */
38     if (ACPI_SUCCESS(as))
39 	    printf("ACPI: machine set to %s mode\n",
40 			    machine.apic_enabled ? "APIC" : "PIC");
41 }
42 
43 static ACPI_STATUS init_acpica(void)
44 {
45 	ACPI_STATUS status;
46 
47 	status = AcpiInitializeSubsystem();
48 	if (ACPI_FAILURE(status))
49 		return status;
50 
51 	status = AcpiInitializeTables(NULL, 16, FALSE);
52 	if (ACPI_FAILURE(status))
53 		return status;
54 
55 	status = AcpiLoadTables();
56 	if (ACPI_FAILURE(status))
57 		return status;
58 
59 	status = AcpiEnableSubsystem(0);
60 	if (ACPI_FAILURE(status))
61 		return status;
62 
63 	status = AcpiInitializeObjects(0);
64 	if (ACPI_FAILURE(status))
65 		return status;
66 
67 	set_machine_mode();
68 
69 	pci_scan_devices();
70 
71 	return AE_OK;
72 }
73 
74 void init_acpi(void)
75 {
76 	ACPI_STATUS acpi_err;
77 	/* test conditions for acpi */
78 	if (sys_getmachine(&machine)) {
79 		printf("ACPI: no machine\n");
80 		return;
81 	}
82 	if (machine.acpi_rsdp == 0) {
83 		printf("ACPI: no RSDP\n");
84 		return;
85 	}
86 	if (init_mem_priv()) {
87 		printf("ACPI: no mem access\n");
88 		return;
89 	}
90 
91 	if ((acpi_err = init_acpica()) == AE_OK) {
92 		acpi_enabled = 1;
93 		printf("ACPI: ACPI enabled\n");
94 	}
95 	else {
96 		acpi_enabled = 0;
97 		printf("ACPI: ACPI failed with err %d\n", acpi_err);
98 	}
99 }
100 
101 static int sef_cb_init_fresh(int type, sef_init_info_t *info)
102 {
103 	init_acpi();
104 
105 	return OK;
106 }
107 
108 static void sef_local_startup()
109 {
110   /* Register init callbacks. */
111   sef_setcb_init_fresh(sef_cb_init_fresh);
112   sef_setcb_init_lu(sef_cb_init_fresh);
113   sef_setcb_init_restart(sef_cb_init_fresh);
114 
115   /* Register live update callbacks. */
116   sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
117   sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
118 
119   /* Let SEF perform startup. */
120   sef_startup();
121 }
122 
123 int main(void)
124 {
125 	int err;
126 	message m;
127 	int ipc_status;
128 
129 	sef_local_startup();
130 
131 	for(;;) {
132 		err = driver_receive(ANY, &m, &ipc_status);
133 		if (err != OK) {
134 			printf("ACPI: driver_receive failed: %d\n", err);
135 			continue;
136 		}
137 
138 		switch (((struct acpi_request_hdr *)&m)->request) {
139 		case ACPI_REQ_GET_IRQ:
140 			do_get_irq(&m);
141 			break;
142 		case ACPI_REQ_MAP_BRIDGE:
143 			do_map_bridge(&m);
144 			break;
145 		default:
146 			printf("ACPI: ignoring unsupported request %d "
147 				"from %d\n",
148 				((struct acpi_request_hdr *)&m)->request,
149 				((struct acpi_request_hdr *)&m)->m_source);
150 		}
151 
152 		err = ipc_send(m.m_source, &m);
153 		if (err != OK) {
154 			printf("ACPI: ipc_send failed: %d\n", err);
155 		}
156 	}
157 }
158