1 1.2 riastrad /* $NetBSD: module.c,v 1.2 2022/09/21 14:30:01 riastradh Exp $ */ 2 1.1 jmcneill 3 1.1 jmcneill /*- 4 1.1 jmcneill * Copyright (c) 2020 The NetBSD Foundation, Inc. 5 1.1 jmcneill * All rights reserved. 6 1.1 jmcneill * 7 1.1 jmcneill * This code is derived from software contributed to The NetBSD Foundation 8 1.1 jmcneill * by Jared McNeill <jmcneill (at) invisible.ca>. 9 1.1 jmcneill * 10 1.1 jmcneill * Redistribution and use in source and binary forms, with or without 11 1.1 jmcneill * modification, are permitted provided that the following conditions 12 1.1 jmcneill * are met: 13 1.1 jmcneill * 1. Redistributions of source code must retain the above copyright 14 1.1 jmcneill * notice, this list of conditions and the following disclaimer. 15 1.1 jmcneill * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 jmcneill * notice, this list of conditions and the following disclaimer in the 17 1.1 jmcneill * documentation and/or other materials provided with the distribution. 18 1.1 jmcneill * 19 1.1 jmcneill * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 jmcneill * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 jmcneill * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 jmcneill * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 jmcneill * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 jmcneill * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 jmcneill * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 jmcneill * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 jmcneill * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 jmcneill * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 jmcneill * POSSIBILITY OF SUCH DAMAGE. 30 1.1 jmcneill */ 31 1.1 jmcneill 32 1.1 jmcneill #include "efiboot.h" 33 1.1 jmcneill #include "module.h" 34 1.1 jmcneill 35 1.1 jmcneill #include <sys/queue.h> 36 1.1 jmcneill 37 1.1 jmcneill int module_enabled = 1; 38 1.1 jmcneill char module_prefix[128]; 39 1.1 jmcneill 40 1.1 jmcneill struct boot_module { 41 1.1 jmcneill char *module_name; 42 1.1 jmcneill TAILQ_ENTRY(boot_module) entries; 43 1.1 jmcneill }; 44 1.1 jmcneill TAILQ_HEAD(, boot_module) boot_modules = TAILQ_HEAD_INITIALIZER(boot_modules); 45 1.1 jmcneill 46 1.1 jmcneill static const char * 47 1.1 jmcneill module_machine(void) 48 1.1 jmcneill { 49 1.1 jmcneill return EFIBOOT_MODULE_MACHINE; 50 1.1 jmcneill } 51 1.1 jmcneill 52 1.1 jmcneill static void 53 1.1 jmcneill module_set_prefix(const char *kernel_path) 54 1.1 jmcneill { 55 1.1 jmcneill #ifdef KERNEL_DIR 56 1.1 jmcneill char *ptr = strrchr(kernel_path, '/'); 57 1.1 jmcneill if (ptr) 58 1.1 jmcneill *ptr = '\0'; 59 1.1 jmcneill snprintf(module_prefix, sizeof(module_prefix), "%s/modules", kernel_path); 60 1.1 jmcneill if (ptr) 61 1.1 jmcneill *ptr = '/'; 62 1.1 jmcneill #else 63 1.1 jmcneill const u_int vmajor = netbsd_version / 100000000; 64 1.1 jmcneill const u_int vminor = netbsd_version / 1000000 % 100; 65 1.2 riastrad const u_int vpatch = netbsd_version / 100 % 10000; 66 1.1 jmcneill 67 1.1 jmcneill if (vminor == 99) { 68 1.1 jmcneill snprintf(module_prefix, sizeof(module_prefix), 69 1.1 jmcneill "/stand/%s/%u.%u.%u/modules", module_machine(), 70 1.1 jmcneill vmajor, vminor, vpatch); 71 1.1 jmcneill } else if (vmajor != 0) { 72 1.1 jmcneill snprintf(module_prefix, sizeof(module_prefix), 73 1.1 jmcneill "/stand/%s/%u.%u/modules", module_machine(), 74 1.1 jmcneill vmajor, vminor); 75 1.1 jmcneill } 76 1.1 jmcneill #endif 77 1.1 jmcneill } 78 1.1 jmcneill 79 1.1 jmcneill void 80 1.1 jmcneill module_init(const char *kernel_path) 81 1.1 jmcneill { 82 1.1 jmcneill module_set_prefix(kernel_path); 83 1.1 jmcneill } 84 1.1 jmcneill 85 1.1 jmcneill void 86 1.1 jmcneill module_foreach(void (*fn)(const char *)) 87 1.1 jmcneill { 88 1.1 jmcneill struct boot_module *bm; 89 1.1 jmcneill 90 1.1 jmcneill TAILQ_FOREACH(bm, &boot_modules, entries) { 91 1.1 jmcneill fn(bm->module_name); 92 1.1 jmcneill } 93 1.1 jmcneill } 94 1.1 jmcneill 95 1.1 jmcneill void 96 1.1 jmcneill module_add(const char *module_name) 97 1.1 jmcneill { 98 1.1 jmcneill struct boot_module *bm; 99 1.1 jmcneill 100 1.1 jmcneill /* Trim leading whitespace */ 101 1.1 jmcneill while (*module_name == ' ' || *module_name == '\t') 102 1.1 jmcneill ++module_name; 103 1.1 jmcneill 104 1.1 jmcneill /* Duplicate check */ 105 1.1 jmcneill TAILQ_FOREACH(bm, &boot_modules, entries) { 106 1.1 jmcneill if (strcmp(bm->module_name, module_name) == 0) 107 1.1 jmcneill return; 108 1.1 jmcneill } 109 1.1 jmcneill 110 1.1 jmcneill /* Add to list of modules */ 111 1.1 jmcneill bm = alloc(sizeof(*bm)); 112 1.1 jmcneill const int slen = strlen(module_name) + 1; 113 1.1 jmcneill bm->module_name = alloc(slen); 114 1.1 jmcneill memcpy(bm->module_name, module_name, slen); 115 1.1 jmcneill TAILQ_INSERT_TAIL(&boot_modules, bm, entries); 116 1.1 jmcneill } 117 1.1 jmcneill 118 1.1 jmcneill void 119 1.1 jmcneill module_remove(const char *module_name) 120 1.1 jmcneill { 121 1.1 jmcneill struct boot_module *bm; 122 1.1 jmcneill 123 1.1 jmcneill /* Trim leading whitespace */ 124 1.1 jmcneill while (*module_name == ' ' || *module_name == '\t') 125 1.1 jmcneill ++module_name; 126 1.1 jmcneill 127 1.1 jmcneill TAILQ_FOREACH(bm, &boot_modules, entries) { 128 1.1 jmcneill if (strcmp(bm->module_name, module_name) == 0) { 129 1.1 jmcneill TAILQ_REMOVE(&boot_modules, bm, entries); 130 1.1 jmcneill dealloc(bm->module_name, strlen(bm->module_name) + 1); 131 1.1 jmcneill dealloc(bm, sizeof(*bm)); 132 1.1 jmcneill return; 133 1.1 jmcneill } 134 1.1 jmcneill } 135 1.1 jmcneill } 136 1.1 jmcneill 137 1.1 jmcneill void 138 1.1 jmcneill module_remove_all(void) 139 1.1 jmcneill { 140 1.1 jmcneill struct boot_module *bm; 141 1.1 jmcneill 142 1.1 jmcneill while ((bm = TAILQ_FIRST(&boot_modules)) != NULL) { 143 1.1 jmcneill TAILQ_REMOVE(&boot_modules, bm, entries); 144 1.1 jmcneill dealloc(bm->module_name, strlen(bm->module_name) + 1); 145 1.1 jmcneill dealloc(bm, sizeof(*bm)); 146 1.1 jmcneill } 147 1.1 jmcneill } 148 1.1 jmcneill 149 1.1 jmcneill void 150 1.1 jmcneill module_enable(int onoff) 151 1.1 jmcneill { 152 1.1 jmcneill module_enabled = onoff; 153 1.1 jmcneill } 154