1433d6423SLionel Sambuc #include <minix/driver.h>
2433d6423SLionel Sambuc #include <acpi.h>
3433d6423SLionel Sambuc #include <assert.h>
4433d6423SLionel Sambuc #include <minix/acpi.h>
5433d6423SLionel Sambuc
6433d6423SLionel Sambuc #include "pci.h"
7433d6423SLionel Sambuc
8433d6423SLionel Sambuc int acpi_enabled;
9433d6423SLionel Sambuc struct machine machine;
10433d6423SLionel Sambuc
11433d6423SLionel Sambuc /* don't know where ACPI tables are, we may need to access any memory */
init_mem_priv(void)12433d6423SLionel Sambuc static int init_mem_priv(void)
13433d6423SLionel Sambuc {
14433d6423SLionel Sambuc struct minix_mem_range mr;
15433d6423SLionel Sambuc
16433d6423SLionel Sambuc mr.mr_base = 0;
17433d6423SLionel Sambuc mr.mr_limit = 0xffffffff;
18433d6423SLionel Sambuc
19433d6423SLionel Sambuc return sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mr);
20433d6423SLionel Sambuc }
21433d6423SLionel Sambuc
set_machine_mode(void)22433d6423SLionel Sambuc static void set_machine_mode(void)
23433d6423SLionel Sambuc {
24433d6423SLionel Sambuc ACPI_OBJECT arg1;
25433d6423SLionel Sambuc ACPI_OBJECT_LIST args;
26433d6423SLionel Sambuc ACPI_STATUS as;
27433d6423SLionel Sambuc
28433d6423SLionel Sambuc arg1.Type = ACPI_TYPE_INTEGER;
29433d6423SLionel Sambuc arg1.Integer.Value = machine.apic_enabled ? 1 : 0;
30433d6423SLionel Sambuc args.Count = 1;
31433d6423SLionel Sambuc args.Pointer = &arg1;
32433d6423SLionel Sambuc
33433d6423SLionel Sambuc as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &args, NULL);
34433d6423SLionel Sambuc /*
35433d6423SLionel Sambuc * We can silently ignore failure as it may not be implemented, ACPI should
36433d6423SLionel Sambuc * provide us with correct information anyway
37433d6423SLionel Sambuc */
38433d6423SLionel Sambuc if (ACPI_SUCCESS(as))
39433d6423SLionel Sambuc printf("ACPI: machine set to %s mode\n",
40433d6423SLionel Sambuc machine.apic_enabled ? "APIC" : "PIC");
41433d6423SLionel Sambuc }
42433d6423SLionel Sambuc
init_acpica(void)43433d6423SLionel Sambuc static ACPI_STATUS init_acpica(void)
44433d6423SLionel Sambuc {
45433d6423SLionel Sambuc ACPI_STATUS status;
46433d6423SLionel Sambuc
47433d6423SLionel Sambuc status = AcpiInitializeSubsystem();
48433d6423SLionel Sambuc if (ACPI_FAILURE(status))
49433d6423SLionel Sambuc return status;
50433d6423SLionel Sambuc
51433d6423SLionel Sambuc status = AcpiInitializeTables(NULL, 16, FALSE);
52433d6423SLionel Sambuc if (ACPI_FAILURE(status))
53433d6423SLionel Sambuc return status;
54433d6423SLionel Sambuc
55433d6423SLionel Sambuc status = AcpiLoadTables();
56433d6423SLionel Sambuc if (ACPI_FAILURE(status))
57433d6423SLionel Sambuc return status;
58433d6423SLionel Sambuc
59433d6423SLionel Sambuc status = AcpiEnableSubsystem(0);
60433d6423SLionel Sambuc if (ACPI_FAILURE(status))
61433d6423SLionel Sambuc return status;
62433d6423SLionel Sambuc
63433d6423SLionel Sambuc status = AcpiInitializeObjects(0);
64433d6423SLionel Sambuc if (ACPI_FAILURE(status))
65433d6423SLionel Sambuc return status;
66433d6423SLionel Sambuc
67433d6423SLionel Sambuc set_machine_mode();
68433d6423SLionel Sambuc
69433d6423SLionel Sambuc pci_scan_devices();
70433d6423SLionel Sambuc
71433d6423SLionel Sambuc return AE_OK;
72433d6423SLionel Sambuc }
73433d6423SLionel Sambuc
init_acpi(void)74433d6423SLionel Sambuc void init_acpi(void)
75433d6423SLionel Sambuc {
76433d6423SLionel Sambuc ACPI_STATUS acpi_err;
77433d6423SLionel Sambuc /* test conditions for acpi */
78433d6423SLionel Sambuc if (sys_getmachine(&machine)) {
79433d6423SLionel Sambuc printf("ACPI: no machine\n");
80433d6423SLionel Sambuc return;
81433d6423SLionel Sambuc }
82433d6423SLionel Sambuc if (machine.acpi_rsdp == 0) {
83433d6423SLionel Sambuc printf("ACPI: no RSDP\n");
84433d6423SLionel Sambuc return;
85433d6423SLionel Sambuc }
86433d6423SLionel Sambuc if (init_mem_priv()) {
87433d6423SLionel Sambuc printf("ACPI: no mem access\n");
88433d6423SLionel Sambuc return;
89433d6423SLionel Sambuc }
90433d6423SLionel Sambuc
91433d6423SLionel Sambuc if ((acpi_err = init_acpica()) == AE_OK) {
92433d6423SLionel Sambuc acpi_enabled = 1;
93433d6423SLionel Sambuc printf("ACPI: ACPI enabled\n");
94433d6423SLionel Sambuc }
95433d6423SLionel Sambuc else {
96433d6423SLionel Sambuc acpi_enabled = 0;
97433d6423SLionel Sambuc printf("ACPI: ACPI failed with err %d\n", acpi_err);
98433d6423SLionel Sambuc }
99433d6423SLionel Sambuc }
100433d6423SLionel Sambuc
sef_cb_init_fresh(int type,sef_init_info_t * info)101433d6423SLionel Sambuc static int sef_cb_init_fresh(int type, sef_init_info_t *info)
102433d6423SLionel Sambuc {
103*50b7f13fSCristiano Giuffrida int r;
104*50b7f13fSCristiano Giuffrida
105433d6423SLionel Sambuc init_acpi();
106433d6423SLionel Sambuc
107*50b7f13fSCristiano Giuffrida /* Let SEF know about ACPI special cache word. */
108*50b7f13fSCristiano Giuffrida r = sef_llvm_add_special_mem_region((void*)0xCACACACA, 1,
109*50b7f13fSCristiano Giuffrida "%MMAP_CACHE_WORD");
110*50b7f13fSCristiano Giuffrida if(r < 0) {
111*50b7f13fSCristiano Giuffrida printf("acpi: sef_llvm_add_special_mem_region failed %d\n", r);
112*50b7f13fSCristiano Giuffrida }
113*50b7f13fSCristiano Giuffrida
114*50b7f13fSCristiano Giuffrida /* XXX To-do: acpi requires custom state transfer handlers for
115*50b7f13fSCristiano Giuffrida * unions acpi_operand_object and acpi_generic_state (and nested unions)
116*50b7f13fSCristiano Giuffrida * for generic state transfer to work correctly.
117*50b7f13fSCristiano Giuffrida */
118*50b7f13fSCristiano Giuffrida
119433d6423SLionel Sambuc return OK;
120433d6423SLionel Sambuc }
121433d6423SLionel Sambuc
sef_local_startup()122433d6423SLionel Sambuc static void sef_local_startup()
123433d6423SLionel Sambuc {
124433d6423SLionel Sambuc /* Register init callbacks. */
125433d6423SLionel Sambuc sef_setcb_init_fresh(sef_cb_init_fresh);
126433d6423SLionel Sambuc sef_setcb_init_lu(sef_cb_init_fresh);
127433d6423SLionel Sambuc sef_setcb_init_restart(sef_cb_init_fresh);
128433d6423SLionel Sambuc
129433d6423SLionel Sambuc /* Let SEF perform startup. */
130433d6423SLionel Sambuc sef_startup();
131433d6423SLionel Sambuc }
132433d6423SLionel Sambuc
main(void)133433d6423SLionel Sambuc int main(void)
134433d6423SLionel Sambuc {
135433d6423SLionel Sambuc int err;
136433d6423SLionel Sambuc message m;
137433d6423SLionel Sambuc int ipc_status;
138433d6423SLionel Sambuc
139433d6423SLionel Sambuc sef_local_startup();
140433d6423SLionel Sambuc
141433d6423SLionel Sambuc for(;;) {
142433d6423SLionel Sambuc err = driver_receive(ANY, &m, &ipc_status);
143433d6423SLionel Sambuc if (err != OK) {
144433d6423SLionel Sambuc printf("ACPI: driver_receive failed: %d\n", err);
145433d6423SLionel Sambuc continue;
146433d6423SLionel Sambuc }
147433d6423SLionel Sambuc
148433d6423SLionel Sambuc switch (((struct acpi_request_hdr *)&m)->request) {
149433d6423SLionel Sambuc case ACPI_REQ_GET_IRQ:
150433d6423SLionel Sambuc do_get_irq(&m);
151433d6423SLionel Sambuc break;
152433d6423SLionel Sambuc case ACPI_REQ_MAP_BRIDGE:
153433d6423SLionel Sambuc do_map_bridge(&m);
154433d6423SLionel Sambuc break;
155433d6423SLionel Sambuc default:
156433d6423SLionel Sambuc printf("ACPI: ignoring unsupported request %d "
157433d6423SLionel Sambuc "from %d\n",
158433d6423SLionel Sambuc ((struct acpi_request_hdr *)&m)->request,
159433d6423SLionel Sambuc ((struct acpi_request_hdr *)&m)->m_source);
160433d6423SLionel Sambuc }
161433d6423SLionel Sambuc
162433d6423SLionel Sambuc err = ipc_send(m.m_source, &m);
163433d6423SLionel Sambuc if (err != OK) {
164433d6423SLionel Sambuc printf("ACPI: ipc_send failed: %d\n", err);
165433d6423SLionel Sambuc }
166433d6423SLionel Sambuc }
167433d6423SLionel Sambuc }
168