1 /*- 2 * $Id:$ 3 */ 4 5 #include "splash.h" 6 7 #if NSPLASH > 0 8 9 #include <sys/param.h> 10 #include <sys/systm.h> 11 #include <sys/kernel.h> 12 #include <sys/malloc.h> 13 #include <sys/linker.h> 14 15 #include <machine/console.h> 16 17 #include <dev/fb/fbreg.h> 18 #include <dev/fb/splashreg.h> 19 20 /* video adapter and image decoder */ 21 static video_adapter_t *splash_adp; 22 static splash_decoder_t *splash_decoder; 23 24 /* decoder candidates */ 25 static int decoders; 26 static splash_decoder_t **decoder_set; 27 #define DECODER_ARRAY_DELTA 4 28 29 /* splash image data file */ 30 static void *splash_image_data; 31 static size_t splash_image_size; 32 33 /* console driver callback */ 34 static int (*splash_callback)(int); 35 36 static int 37 splash_find_image(void) 38 { 39 caddr_t image_module; 40 caddr_t p; 41 42 if (splash_image_data == NULL) { 43 image_module = preload_search_by_type(SPLASH_IMAGE); 44 if (image_module == NULL) 45 return ENOENT; 46 p = preload_search_info(image_module, MODINFO_ADDR); 47 if (p == NULL) 48 return ENOENT; 49 splash_image_data = *(void **)p; 50 p = preload_search_info(image_module, MODINFO_SIZE); 51 if (p == NULL) 52 return ENOENT; 53 splash_image_size = *(size_t *)p; 54 } 55 return 0; 56 } 57 58 static int 59 splash_test(splash_decoder_t *decoder) 60 { 61 if ((*decoder->init)(splash_adp, splash_image_data, splash_image_size)) 62 return ENODEV; /* XXX */ 63 if (bootverbose) 64 printf("splash: image decoder found: %s\n", decoder->name); 65 splash_decoder = decoder; 66 if (splash_callback != NULL) 67 (*splash_callback)(SPLASH_INIT); 68 return 0; 69 } 70 71 int 72 splash_register(splash_decoder_t *decoder) 73 { 74 splash_decoder_t **p; 75 int i; 76 77 /* only one decoder can be active */ 78 if (splash_decoder != NULL) 79 return ENODEV; /* XXX */ 80 81 /* if the splash image is not in memory, abort */ 82 splash_find_image(); 83 if (bootverbose) 84 printf("splash: image@%p, size:%u\n", 85 splash_image_data, splash_image_size); 86 if (splash_image_data == NULL) 87 return ENOENT; 88 89 /* 90 * If the video card has aleady been initialized, test this 91 * decoder immediately. 92 */ 93 if (splash_adp != NULL) 94 return splash_test(decoder); 95 96 /* register the decoder for later use */ 97 for (i = 0; i < decoders; ++i) { 98 if (decoder_set[i] == NULL) 99 break; 100 } 101 if ((i >= decoders) && (decoders % DECODER_ARRAY_DELTA) == 0) { 102 p = malloc(sizeof(*p)*(decoders + DECODER_ARRAY_DELTA), 103 M_DEVBUF, M_NOWAIT); 104 if (p == NULL) 105 return ENOMEM; 106 if (decoder_set != NULL) 107 bcopy(decoder_set, p, sizeof(*p)*decoders); 108 free(decoder_set, M_DEVBUF); 109 decoder_set = p; 110 i = decoders++; 111 } 112 decoder_set[i] = decoder; 113 return 0; 114 } 115 116 int 117 splash_unregister(splash_decoder_t *decoder) 118 { 119 int error; 120 int i; 121 122 if (splash_decoder == decoder) { 123 if ((error = splash_term(splash_adp)) != 0) 124 return error; 125 } 126 for (i = 0; i < decoders; ++i) { 127 if (decoder_set[i] == decoder) { 128 decoder_set[i] = NULL; 129 break; 130 } 131 } 132 return 0; 133 } 134 135 int 136 splash_init(video_adapter_t *adp, int (*callback)(int)) 137 { 138 int i; 139 140 splash_adp = adp; 141 splash_callback = callback; 142 143 /* try registered decoders with this adapter and loaded image */ 144 splash_decoder = NULL; 145 splash_find_image(); 146 if (splash_image_data == NULL) 147 return 0; 148 for (i = 0; i < decoders; ++i) { 149 if (decoder_set[i] == NULL) 150 continue; 151 if (splash_test(decoder_set[i]) == 0) 152 break; 153 } 154 return 0; 155 } 156 157 int 158 splash_term(video_adapter_t *adp) 159 { 160 int error = 0; 161 162 if (splash_decoder != NULL) { 163 if (splash_callback != NULL) 164 error = (*splash_callback)(SPLASH_TERM); 165 if (error == 0) 166 error = (*splash_decoder->term)(adp); 167 if (error == 0) 168 splash_decoder = NULL; 169 } 170 return error; 171 } 172 173 int 174 splash(video_adapter_t *adp, int on) 175 { 176 if (splash_decoder != NULL) 177 return (*splash_decoder->splash)(adp, on); 178 return ENODEV; 179 } 180 181 #endif /* NSPLASH > 0 */ 182