158 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <minix/driver.h>
 | |
| #include <acpi.h>
 | |
| #include <assert.h>
 | |
| #include <minix/acpi.h>
 | |
| 
 | |
| #include "pci.h"
 | |
| 
 | |
| int acpi_enabled;
 | |
| struct machine machine;
 | |
| 
 | |
| /* don't know where ACPI tables are, we may need to access any memory */
 | |
| static int init_mem_priv(void)
 | |
| {
 | |
| 	struct minix_mem_range mr;
 | |
| 
 | |
| 	mr.mr_base = 0;
 | |
| 	mr.mr_limit = 0xffffffff;
 | |
| 
 | |
| 	return sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mr);
 | |
| }
 | |
| 
 | |
| static void set_machine_mode(void)
 | |
| {
 | |
|     ACPI_OBJECT arg1;
 | |
|     ACPI_OBJECT_LIST args;
 | |
|     ACPI_STATUS as;
 | |
| 
 | |
|     arg1.Type = ACPI_TYPE_INTEGER;
 | |
|     arg1.Integer.Value = machine.apic_enabled ? 1 : 0;
 | |
|     args.Count = 1;
 | |
|     args.Pointer = &arg1;
 | |
| 
 | |
|     as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &args, NULL);
 | |
|     /*
 | |
|      * We can silently ignore failure as it may not be implemented, ACPI should
 | |
|      * provide us with correct information anyway
 | |
|      */
 | |
|     if (ACPI_SUCCESS(as))
 | |
| 	    printf("ACPI: machine set to %s mode\n",
 | |
| 			    machine.apic_enabled ? "APIC" : "PIC");
 | |
| }
 | |
| 
 | |
| static ACPI_STATUS init_acpica(void)
 | |
| {
 | |
| 	ACPI_STATUS status;
 | |
| 
 | |
| 	status = AcpiInitializeSubsystem();
 | |
| 	if (ACPI_FAILURE(status))
 | |
| 		return status;
 | |
| 
 | |
| 	status = AcpiInitializeTables(NULL, 16, FALSE);
 | |
| 	if (ACPI_FAILURE(status))
 | |
| 		return status;
 | |
| 
 | |
| 	status = AcpiLoadTables();
 | |
| 	if (ACPI_FAILURE(status))
 | |
| 		return status;
 | |
| 
 | |
| 	status = AcpiEnableSubsystem(0);
 | |
| 	if (ACPI_FAILURE(status))
 | |
| 		return status;
 | |
| 
 | |
| 	status = AcpiInitializeObjects(0);
 | |
| 	if (ACPI_FAILURE(status))
 | |
| 		return status;
 | |
| 
 | |
| 	set_machine_mode();
 | |
| 	
 | |
| 	pci_scan_devices();
 | |
| 
 | |
| 	return AE_OK;
 | |
| }
 | |
| 
 | |
| void init_acpi(void)
 | |
| {
 | |
| 	ACPI_STATUS acpi_err;
 | |
| 	/* test conditions for acpi */
 | |
| 	if (sys_getmachine(&machine)) {
 | |
| 		printf("ACPI: no machine\n");
 | |
| 		return;
 | |
| 	}
 | |
| 	if (machine.acpi_rsdp == 0) {
 | |
| 		printf("ACPI: no RSDP\n");
 | |
| 		return;
 | |
| 	}
 | |
| 	if (init_mem_priv()) {
 | |
| 		printf("ACPI: no mem access\n");
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	if ((acpi_err = init_acpica()) == AE_OK) {
 | |
| 		acpi_enabled = 1;
 | |
| 		printf("ACPI: ACPI enabled\n");
 | |
| 	}
 | |
| 	else {
 | |
| 		acpi_enabled = 0;
 | |
| 		printf("ACPI: ACPI failed with err %d\n", acpi_err);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static int sef_cb_init_fresh(int type, sef_init_info_t *info)
 | |
| {
 | |
| 	init_acpi();
 | |
| 
 | |
| 	return OK;
 | |
| }
 | |
| 
 | |
| static void sef_local_startup()
 | |
| {
 | |
|   /* Register init callbacks. */
 | |
|   sef_setcb_init_fresh(sef_cb_init_fresh);
 | |
|   sef_setcb_init_lu(sef_cb_init_fresh);
 | |
|   sef_setcb_init_restart(sef_cb_init_fresh);
 | |
| 
 | |
|   /* Register live update callbacks. */
 | |
|   sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
 | |
|   sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
 | |
| 
 | |
|   /* Let SEF perform startup. */
 | |
|   sef_startup();
 | |
| }
 | |
| 
 | |
| int main(void)
 | |
| {
 | |
| 	int err;
 | |
| 	message m;
 | |
| 	int ipc_status;
 | |
| 
 | |
| 	sef_local_startup();
 | |
| 
 | |
| 	for(;;) {
 | |
| 		err = driver_receive(ANY, &m, &ipc_status);
 | |
| 		if (err != OK) {
 | |
| 			printf("ACPI: driver_receive failed: %d\n", err);
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		switch (((struct acpi_request_hdr *)&m)->request) {
 | |
| 		case ACPI_REQ_GET_IRQ:
 | |
| 			do_get_irq(&m);
 | |
| 			break;
 | |
| 		case ACPI_REQ_MAP_BRIDGE:
 | |
| 			do_map_bridge(&m);
 | |
| 			break;
 | |
| 		default:
 | |
| 			printf("ACPI: ignoring unsupported request %d "
 | |
| 				"from %d\n",
 | |
| 				((struct acpi_request_hdr *)&m)->request,
 | |
| 				((struct acpi_request_hdr *)&m)->m_source);
 | |
| 		}
 | |
| 
 | |
| 		err = send(m.m_source, &m);
 | |
| 		if (err != OK) {
 | |
| 			printf("ACPI: send failed: %d\n", err);
 | |
| 		}
 | |
| 	}
 | |
| }
 | 
