1617b9080SKazutaka YOKOTA /*- 2617b9080SKazutaka YOKOTA * $Id:$ 3617b9080SKazutaka YOKOTA */ 4617b9080SKazutaka YOKOTA 5617b9080SKazutaka YOKOTA #include "splash.h" 6617b9080SKazutaka YOKOTA 7617b9080SKazutaka YOKOTA #if NSPLASH > 0 8617b9080SKazutaka YOKOTA 9617b9080SKazutaka YOKOTA #include <sys/param.h> 10617b9080SKazutaka YOKOTA #include <sys/systm.h> 11617b9080SKazutaka YOKOTA #include <sys/kernel.h> 12617b9080SKazutaka YOKOTA #include <sys/malloc.h> 13617b9080SKazutaka YOKOTA #include <sys/linker.h> 14617b9080SKazutaka YOKOTA 15617b9080SKazutaka YOKOTA #include <machine/console.h> 16617b9080SKazutaka YOKOTA 17617b9080SKazutaka YOKOTA #include <dev/fb/fbreg.h> 18617b9080SKazutaka YOKOTA #include <dev/fb/splashreg.h> 19617b9080SKazutaka YOKOTA 20617b9080SKazutaka YOKOTA /* video adapter and image decoder */ 21617b9080SKazutaka YOKOTA static video_adapter_t *splash_adp; 22617b9080SKazutaka YOKOTA static splash_decoder_t *splash_decoder; 23617b9080SKazutaka YOKOTA 24617b9080SKazutaka YOKOTA /* decoder candidates */ 25617b9080SKazutaka YOKOTA static int decoders; 26617b9080SKazutaka YOKOTA static splash_decoder_t **decoder_set; 27617b9080SKazutaka YOKOTA #define DECODER_ARRAY_DELTA 4 28617b9080SKazutaka YOKOTA 29617b9080SKazutaka YOKOTA /* splash image data file */ 30617b9080SKazutaka YOKOTA static void *splash_image_data; 31617b9080SKazutaka YOKOTA static size_t splash_image_size; 32617b9080SKazutaka YOKOTA 33617b9080SKazutaka YOKOTA /* console driver callback */ 34617b9080SKazutaka YOKOTA static int (*splash_callback)(int); 35617b9080SKazutaka YOKOTA 36617b9080SKazutaka YOKOTA static int 37617b9080SKazutaka YOKOTA splash_find_image(void) 38617b9080SKazutaka YOKOTA { 39617b9080SKazutaka YOKOTA caddr_t image_module; 40617b9080SKazutaka YOKOTA caddr_t p; 41617b9080SKazutaka YOKOTA 42617b9080SKazutaka YOKOTA if (splash_image_data == NULL) { 43617b9080SKazutaka YOKOTA image_module = preload_search_by_type(SPLASH_IMAGE); 44617b9080SKazutaka YOKOTA if (image_module == NULL) 45617b9080SKazutaka YOKOTA return ENOENT; 46617b9080SKazutaka YOKOTA p = preload_search_info(image_module, MODINFO_ADDR); 47617b9080SKazutaka YOKOTA if (p == NULL) 48617b9080SKazutaka YOKOTA return ENOENT; 49617b9080SKazutaka YOKOTA splash_image_data = *(void **)p; 50617b9080SKazutaka YOKOTA p = preload_search_info(image_module, MODINFO_SIZE); 51617b9080SKazutaka YOKOTA if (p == NULL) 52617b9080SKazutaka YOKOTA return ENOENT; 53617b9080SKazutaka YOKOTA splash_image_size = *(size_t *)p; 54617b9080SKazutaka YOKOTA } 55617b9080SKazutaka YOKOTA return 0; 56617b9080SKazutaka YOKOTA } 57617b9080SKazutaka YOKOTA 58617b9080SKazutaka YOKOTA static int 59617b9080SKazutaka YOKOTA splash_test(splash_decoder_t *decoder) 60617b9080SKazutaka YOKOTA { 61617b9080SKazutaka YOKOTA if ((*decoder->init)(splash_adp, splash_image_data, splash_image_size)) 62617b9080SKazutaka YOKOTA return ENODEV; /* XXX */ 63617b9080SKazutaka YOKOTA if (bootverbose) 64617b9080SKazutaka YOKOTA printf("splash: image decoder found: %s\n", decoder->name); 65617b9080SKazutaka YOKOTA splash_decoder = decoder; 66617b9080SKazutaka YOKOTA if (splash_callback != NULL) 67617b9080SKazutaka YOKOTA (*splash_callback)(SPLASH_INIT); 68617b9080SKazutaka YOKOTA return 0; 69617b9080SKazutaka YOKOTA } 70617b9080SKazutaka YOKOTA 71617b9080SKazutaka YOKOTA int 72617b9080SKazutaka YOKOTA splash_register(splash_decoder_t *decoder) 73617b9080SKazutaka YOKOTA { 74617b9080SKazutaka YOKOTA splash_decoder_t **p; 75617b9080SKazutaka YOKOTA int i; 76617b9080SKazutaka YOKOTA 77617b9080SKazutaka YOKOTA /* only one decoder can be active */ 78617b9080SKazutaka YOKOTA if (splash_decoder != NULL) 79617b9080SKazutaka YOKOTA return ENODEV; /* XXX */ 80617b9080SKazutaka YOKOTA 81617b9080SKazutaka YOKOTA /* if the splash image is not in memory, abort */ 82617b9080SKazutaka YOKOTA splash_find_image(); 83617b9080SKazutaka YOKOTA if (bootverbose) 84617b9080SKazutaka YOKOTA printf("splash: image@%p, size:%u\n", 85617b9080SKazutaka YOKOTA splash_image_data, splash_image_size); 86617b9080SKazutaka YOKOTA if (splash_image_data == NULL) 87617b9080SKazutaka YOKOTA return ENOENT; 88617b9080SKazutaka YOKOTA 89617b9080SKazutaka YOKOTA /* 90617b9080SKazutaka YOKOTA * If the video card has aleady been initialized, test this 91617b9080SKazutaka YOKOTA * decoder immediately. 92617b9080SKazutaka YOKOTA */ 93617b9080SKazutaka YOKOTA if (splash_adp != NULL) 94617b9080SKazutaka YOKOTA return splash_test(decoder); 95617b9080SKazutaka YOKOTA 96617b9080SKazutaka YOKOTA /* register the decoder for later use */ 97617b9080SKazutaka YOKOTA for (i = 0; i < decoders; ++i) { 98617b9080SKazutaka YOKOTA if (decoder_set[i] == NULL) 99617b9080SKazutaka YOKOTA break; 100617b9080SKazutaka YOKOTA } 101617b9080SKazutaka YOKOTA if ((i >= decoders) && (decoders % DECODER_ARRAY_DELTA) == 0) { 102617b9080SKazutaka YOKOTA p = malloc(sizeof(*p)*(decoders + DECODER_ARRAY_DELTA), 103617b9080SKazutaka YOKOTA M_DEVBUF, M_NOWAIT); 104617b9080SKazutaka YOKOTA if (p == NULL) 105617b9080SKazutaka YOKOTA return ENOMEM; 106617b9080SKazutaka YOKOTA if (decoder_set != NULL) 107617b9080SKazutaka YOKOTA bcopy(decoder_set, p, sizeof(*p)*decoders); 108617b9080SKazutaka YOKOTA free(decoder_set, M_DEVBUF); 109617b9080SKazutaka YOKOTA decoder_set = p; 110617b9080SKazutaka YOKOTA i = decoders++; 111617b9080SKazutaka YOKOTA } 112617b9080SKazutaka YOKOTA decoder_set[i] = decoder; 113617b9080SKazutaka YOKOTA return 0; 114617b9080SKazutaka YOKOTA } 115617b9080SKazutaka YOKOTA 116617b9080SKazutaka YOKOTA int 117617b9080SKazutaka YOKOTA splash_unregister(splash_decoder_t *decoder) 118617b9080SKazutaka YOKOTA { 119617b9080SKazutaka YOKOTA int error; 120617b9080SKazutaka YOKOTA int i; 121617b9080SKazutaka YOKOTA 122617b9080SKazutaka YOKOTA if (splash_decoder == decoder) { 123617b9080SKazutaka YOKOTA if ((error = splash_term(splash_adp)) != 0) 124617b9080SKazutaka YOKOTA return error; 125617b9080SKazutaka YOKOTA } 126617b9080SKazutaka YOKOTA for (i = 0; i < decoders; ++i) { 127617b9080SKazutaka YOKOTA if (decoder_set[i] == decoder) { 128617b9080SKazutaka YOKOTA decoder_set[i] = NULL; 129617b9080SKazutaka YOKOTA break; 130617b9080SKazutaka YOKOTA } 131617b9080SKazutaka YOKOTA } 132617b9080SKazutaka YOKOTA return 0; 133617b9080SKazutaka YOKOTA } 134617b9080SKazutaka YOKOTA 135617b9080SKazutaka YOKOTA int 136617b9080SKazutaka YOKOTA splash_init(video_adapter_t *adp, int (*callback)(int)) 137617b9080SKazutaka YOKOTA { 138617b9080SKazutaka YOKOTA int i; 139617b9080SKazutaka YOKOTA 140617b9080SKazutaka YOKOTA splash_adp = adp; 141617b9080SKazutaka YOKOTA splash_callback = callback; 142617b9080SKazutaka YOKOTA 143617b9080SKazutaka YOKOTA /* try registered decoders with this adapter and loaded image */ 144617b9080SKazutaka YOKOTA splash_decoder = NULL; 145617b9080SKazutaka YOKOTA splash_find_image(); 146617b9080SKazutaka YOKOTA if (splash_image_data == NULL) 147617b9080SKazutaka YOKOTA return 0; 148617b9080SKazutaka YOKOTA for (i = 0; i < decoders; ++i) { 149617b9080SKazutaka YOKOTA if (decoder_set[i] == NULL) 150617b9080SKazutaka YOKOTA continue; 151617b9080SKazutaka YOKOTA if (splash_test(decoder_set[i]) == 0) 152617b9080SKazutaka YOKOTA break; 153617b9080SKazutaka YOKOTA } 154617b9080SKazutaka YOKOTA return 0; 155617b9080SKazutaka YOKOTA } 156617b9080SKazutaka YOKOTA 157617b9080SKazutaka YOKOTA int 158617b9080SKazutaka YOKOTA splash_term(video_adapter_t *adp) 159617b9080SKazutaka YOKOTA { 160617b9080SKazutaka YOKOTA int error = 0; 161617b9080SKazutaka YOKOTA 162617b9080SKazutaka YOKOTA if (splash_decoder != NULL) { 163617b9080SKazutaka YOKOTA if (splash_callback != NULL) 164617b9080SKazutaka YOKOTA error = (*splash_callback)(SPLASH_TERM); 165617b9080SKazutaka YOKOTA if (error == 0) 166617b9080SKazutaka YOKOTA error = (*splash_decoder->term)(adp); 167617b9080SKazutaka YOKOTA if (error == 0) 168617b9080SKazutaka YOKOTA splash_decoder = NULL; 169617b9080SKazutaka YOKOTA } 170617b9080SKazutaka YOKOTA return error; 171617b9080SKazutaka YOKOTA } 172617b9080SKazutaka YOKOTA 173617b9080SKazutaka YOKOTA int 174617b9080SKazutaka YOKOTA splash(video_adapter_t *adp, int on) 175617b9080SKazutaka YOKOTA { 176617b9080SKazutaka YOKOTA if (splash_decoder != NULL) 177617b9080SKazutaka YOKOTA return (*splash_decoder->splash)(adp, on); 178617b9080SKazutaka YOKOTA return ENODEV; 179617b9080SKazutaka YOKOTA } 180617b9080SKazutaka YOKOTA 181617b9080SKazutaka YOKOTA #endif /* NSPLASH > 0 */ 182