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);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |