xref: /haiku/src/add-ons/kernel/busses/random/ccp/ccp_acpi.cpp (revision 52c4471a3024d2eb81fe88e2c3982b9f8daa5e56)
1 /*
2  * Copyright 2022, Jérôme Duval, jerome.duval@gmail.com.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <new>
8 #include <stdio.h>
9 #include <string.h>
10 
11 #include <ACPI.h>
12 #include <ByteOrder.h>
13 #include <condition_variable.h>
14 
15 extern "C" {
16 #	include "acpi.h"
17 }
18 
19 
20 #define DRIVER_NAME "ccp_rng_acpi"
21 #include "ccp.h"
22 
23 
24 typedef struct {
25 	ccp_device_info info;
26 	acpi_device_module_info* acpi;
27 	acpi_device device;
28 
29 } ccp_acpi_sim_info;
30 
31 
32 struct ccp_crs {
33 	uint32	addr_bas;
34 	uint32	addr_len;
35 };
36 
37 
38 static acpi_status
39 ccp_scan_parse_callback(ACPI_RESOURCE *res, void *context)
40 {
41 	struct ccp_crs* crs = (struct ccp_crs*)context;
42 
43 	if (res->Type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) {
44 		crs->addr_bas = res->Data.FixedMemory32.Address;
45 		crs->addr_len = res->Data.FixedMemory32.AddressLength;
46 	}
47 
48 	return B_OK;
49 }
50 
51 
52 //	#pragma mark -
53 
54 
55 static status_t
56 init_device(device_node* node, void** device_cookie)
57 {
58 	CALLED();
59 	status_t status = B_OK;
60 
61 	ccp_acpi_sim_info* bus = (ccp_acpi_sim_info*)calloc(1,
62 		sizeof(ccp_acpi_sim_info));
63 	if (bus == NULL)
64 		return B_NO_MEMORY;
65 
66 	acpi_device_module_info* acpi;
67 	acpi_device device;
68 	{
69 		device_node* acpiParent = gDeviceManager->get_parent_node(node);
70 		gDeviceManager->get_driver(acpiParent, (driver_module_info**)&acpi,
71 			(void**)&device);
72 		gDeviceManager->put_node(acpiParent);
73 	}
74 
75 	bus->acpi = acpi;
76 	bus->device = device;
77 
78 	struct ccp_crs crs;
79 	status = acpi->walk_resources(device, (ACPI_STRING)"_CRS",
80 		ccp_scan_parse_callback, &crs);
81 	if (status != B_OK) {
82 		ERROR("Error while getting resouces\n");
83 		free(bus);
84 		return status;
85 	}
86 	if (crs.addr_bas == 0 || crs.addr_len == 0) {
87 		TRACE("skipping non configured CCP devices\n");
88 		free(bus);
89 		return B_BAD_VALUE;
90 	}
91 
92 	bus->info.base_addr = crs.addr_bas;
93 	bus->info.map_size = crs.addr_len;
94 
95 	*device_cookie = bus;
96 	return B_OK;
97 }
98 
99 
100 static void
101 uninit_device(void* device_cookie)
102 {
103 	ccp_acpi_sim_info* bus = (ccp_acpi_sim_info*)device_cookie;
104 	free(bus);
105 }
106 
107 
108 static status_t
109 register_device(device_node* parent)
110 {
111 	device_attr attrs[] = {
112 		{B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {.string = "CCP ACPI"}},
113 		{B_DEVICE_BUS, B_STRING_TYPE, {.string = "CCP"}},
114 		{B_DEVICE_FIXED_CHILD, B_STRING_TYPE, {.string = CCP_DEVICE_MODULE_NAME}},
115 		{}
116 	};
117 
118 	return gDeviceManager->register_node(parent,
119 		CCP_ACPI_DEVICE_MODULE_NAME, attrs, NULL, NULL);
120 }
121 
122 
123 static float
124 supports_device(device_node* parent)
125 {
126 	const char* bus;
127 
128 	// make sure parent is a CCP ACPI device node
129 	if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)
130 		< B_OK) {
131 		return -1;
132 	}
133 
134 	if (strcmp(bus, "acpi") != 0)
135 		return 0.0f;
136 
137 	// check whether it's really a device
138 	uint32 device_type;
139 	if (gDeviceManager->get_attr_uint32(parent, ACPI_DEVICE_TYPE_ITEM,
140 			&device_type, false) != B_OK
141 		|| device_type != ACPI_TYPE_DEVICE) {
142 		return 0.0;
143 	}
144 
145 	// check whether it's a CCP device
146 	const char *name;
147 	if (gDeviceManager->get_attr_string(parent, ACPI_DEVICE_HID_ITEM, &name,
148 		false) != B_OK) {
149 		return 0.0;
150 	}
151 
152 	if (strcmp(name, "AMDI0C00") == 0) {
153 		TRACE("CCP device found! name %s\n", name);
154 		return 0.6f;
155 	}
156 
157 	return 0.0f;
158 }
159 
160 
161 //	#pragma mark -
162 
163 
164 driver_module_info gCcpAcpiDevice = {
165 	{
166 		CCP_ACPI_DEVICE_MODULE_NAME,
167 		0,
168 		NULL
169 	},
170 
171 	supports_device,
172 	register_device,
173 	init_device,
174 	uninit_device,
175 	NULL,	// register_child_devices,
176 	NULL,	// rescan
177 	NULL,	// device removed
178 };
179 
180 
181