1+ #include <acpi_vfs.h>
2+ #include <driver/disk_driver.h>
3+ #include <memory/vmm.h>
4+ #include <string.h>
5+ #include <assert.h>
6+ #include <stdio.h>
7+
8+ acpi_vfs_mount_data_t create_acpi_vfs_mount_data () {
9+ int entriesXSDT = xsdt ? (xsdt -> header .length - sizeof (sdt_header_t )) / 8 : 0 ;
10+ int entriesRSDT = rsdt ? (rsdt -> header .length - sizeof (sdt_header_t )) / 4 : 0 ;
11+
12+ acpi_vfs_mount_data_t mount_data ;
13+ mount_data .table_count = entriesXSDT + entriesRSDT ;
14+ mount_data .tables = (sdt_header_t * * ) vmm_alloc (sizeof (sdt_header_t * ) * mount_data .table_count );
15+
16+ if (xsdt != NULL ) {
17+ for (uint64_t i = 0 ; i < entriesXSDT ; i ++ ) {
18+ sdt_header_t * acpihdr = (sdt_header_t * ) (uint32_t ) xsdt -> acpiptr [i ];
19+ debugf ("[XSDT] Found ACPI table: %c%c%c%c" , acpihdr -> signature [0 ], acpihdr -> signature [1 ], acpihdr -> signature [2 ], acpihdr -> signature [3 ]);
20+ mount_data .tables [i ] = acpihdr ;
21+ }
22+ }
23+
24+ if (rsdt != NULL ) {
25+ for (uint64_t i = 0 ; i < entriesRSDT ; i ++ ) {
26+ sdt_header_t * acpihdr = (sdt_header_t * ) (rsdt -> acpiptr [i ]);
27+ debugf ("[RSDT] Found ACPI table: %c%c%c%c" , acpihdr -> signature [0 ], acpihdr -> signature [1 ], acpihdr -> signature [2 ], acpihdr -> signature [3 ]);
28+ mount_data .tables [entriesXSDT + i ] = acpihdr ;
29+ }
30+ }
31+
32+ return mount_data ;
33+ }
34+
35+ char * acpi_vfs_name (vfs_mount_t * mount ) {
36+ return "acpi" ;
37+ }
38+
39+ file_t * acpi_vfs_open (vfs_mount_t * mount , char * path , int flags ) {
40+ acpi_vfs_mount_data_t * data = (acpi_vfs_mount_data_t * ) mount -> driver_specific_data ;
41+
42+ char file [0xff ] = { 0 };
43+ while (* (path = copy_until ('/' , path , file )));
44+ debugf ("file: %s" , file );
45+
46+ for (size_t i = 0 ; i < data -> table_count ; i ++ ) {
47+ sdt_header_t * table = data -> tables [i ];
48+ char expected_name [0xff ] = { 0 };
49+ sprintf (expected_name , "%d.%c%c%c%c" , i , table -> signature [0 ], table -> signature [1 ], table -> signature [2 ], table -> signature [3 ]);
50+
51+ if (strcmp (file , expected_name ) == 0 ) {
52+ file_t * file = (file_t * ) vmm_alloc (1 );
53+ memset (file , 0 , sizeof (file_t ));
54+
55+ file -> mount = mount ;
56+ file -> size = table -> length ;
57+ file -> driver_specific_data = table ;
58+
59+ return file ;
60+ }
61+ }
62+
63+ return NULL ;
64+ }
65+
66+ void acpi_vfs_close (vfs_mount_t * mount , file_t * f ) {
67+ vmm_free (f , 1 );
68+ }
69+
70+ void acpi_vfs_read (vfs_mount_t * mount , file_t * f , void * buffer , size_t size , size_t offset ) {
71+ if (offset + size > f -> size ) {
72+ abortf (true, "Attempted to read beyond end of ACPI table file" );
73+ }
74+ memcpy (buffer , & ((char * ) f -> driver_specific_data )[offset ], size );
75+ }
76+
77+
78+ dir_t acpi_vfs_dir_at (vfs_mount_t * mount , int idx , char * path ) {
79+ acpi_vfs_mount_data_t * mount_data = (acpi_vfs_mount_data_t * ) mount -> driver_specific_data ;
80+ if (idx >= mount_data -> table_count ) {
81+ dir_t empty = {
82+ .is_none = true
83+ };
84+ return empty ;
85+ }
86+
87+ sdt_header_t * table = mount_data -> tables [idx ];
88+ dir_t entry = {
89+ .idx = idx ,
90+ .is_none = false,
91+ .type = ENTRY_FILE
92+ };
93+ sprintf (entry .name , "%d.%c%c%c%c" , idx , table -> signature [0 ], table -> signature [1 ], table -> signature [2 ], table -> signature [3 ]);
94+
95+ return entry ;
96+ }
97+
98+ vfs_mount_t * acpi_vfs_mount () {
99+ vfs_mount_t * mount = (vfs_mount_t * ) vmm_alloc (1 );
100+ memset (mount , 0 , 0x1000 );
101+
102+ assert ((sizeof (vfs_mount_t ) + sizeof (acpi_vfs_mount_data_t )) <= 0x1000 );
103+
104+ acpi_vfs_mount_data_t * mount_data = (acpi_vfs_mount_data_t * ) & mount [1 ];
105+ mount -> driver_specific_data = mount_data ;
106+
107+ * mount_data = create_acpi_vfs_mount_data ();
108+
109+ mount -> name = acpi_vfs_name ;
110+ mount -> open = acpi_vfs_open ;
111+ mount -> close = acpi_vfs_close ;
112+ mount -> read = acpi_vfs_read ;
113+ mount -> dir_at = acpi_vfs_dir_at ;
114+
115+ return mount ;
116+ }
0 commit comments