#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(__x86_64__) #include #endif static struct rb_node_link* device_tree = NULL; static spin_lock_t device_tree_lock; struct device* device_create (int id, device_op_func_t* ops, size_t ops_len, device_init_func_t init, device_fini_func_t fini, void* arg) { if (ops_len >= fieldlengthof (struct device, ops)) return NULL; struct device* device = malloc (sizeof (*device)); if (device == NULL) return NULL; memset (device, 0, sizeof (*device)); device->id = id; device->init = init; device->fini = fini; if (ops != NULL) memcpy (device->ops, ops, ops_len * sizeof (device_op_func_t)); if (!device->init (device, arg)) { free (device); return NULL; } spin_lock (&device_tree_lock); rbtree_insert (struct device, &device_tree, &device->device_tree_link, device_tree_link, id); spin_unlock (&device_tree_lock); return device; } void device_delete (struct device* device) { spin_lock (&device_tree_lock); spin_lock (&device->lock); rbtree_delete (&device_tree, &device->device_tree_link); spin_unlock (&device->lock); spin_unlock (&device_tree_lock); device->fini (device); free (device); } struct device* device_find (int id) { struct device* device = NULL; spin_lock (&device_tree_lock); rbtree_find (struct device, &device_tree, id, device, device_tree_link, id); spin_unlock (&device_tree_lock); return device; } void terminal_device_init (void) { device_op_func_t ops[] = { [TERMINAL_PUTSTR] = &terminal_putstr, }; device_create (TERMINAL_DEVICE, ops, lengthof (ops), &terminal_init, &terminal_fini, NULL); } void ramdisk_device_init (void) { device_op_func_t ops[] = { [XDRV_GET_SIZE] = &ramdrv_get_size, [XDRV_GET_SECTOR_SIZE] = &ramdrv_get_sector_size, [XDRV_GET_DEVICE_TYPE] = &ramdrv_get_device_type, [XDRV_READ] = &ramdrv_read, }; struct limine_module_response* module = limine_module_request.response; const char* ramdisk_path = "/boot/mop3dist.tar"; struct limine_file* file = NULL; for (size_t i = 0; i < module->module_count; i++) { file = module->modules[i]; if (strncmp (file->path, ramdisk_path, strlen (ramdisk_path)) == 0) break; } struct ramdrv_init init = { .total_size = file->size, .sector_size = 1024, .buffer = file->address, }; device_create (RAMDISK_DEVICE, ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init); } #if defined(__x86_64__) void ps2kb_device_init (void) { device_op_func_t ops[] = { [KB_READ_KEY] = &ps2kb_read_key, }; device_create (KB_DEVICE, ops, lengthof (ops), &ps2kb_init, &ps2kb_fini, NULL); } #endif void devices_init (void) { terminal_device_init (); ramdisk_device_init (); #if defined(__x86_64__) ps2kb_device_init (); #endif }