1617b9080SKazutaka YOKOTA /*- 2559e7c1bSKazutaka YOKOTA * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 3559e7c1bSKazutaka YOKOTA * All rights reserved. 4559e7c1bSKazutaka YOKOTA * 5559e7c1bSKazutaka YOKOTA * Redistribution and use in source and binary forms, with or without 6559e7c1bSKazutaka YOKOTA * modification, are permitted provided that the following conditions 7559e7c1bSKazutaka YOKOTA * are met: 8559e7c1bSKazutaka YOKOTA * 1. Redistributions of source code must retain the above copyright 9559e7c1bSKazutaka YOKOTA * notice, this list of conditions and the following disclaimer as 10559e7c1bSKazutaka YOKOTA * the first lines of this file unmodified. 11559e7c1bSKazutaka YOKOTA * 2. Redistributions in binary form must reproduce the above copyright 12559e7c1bSKazutaka YOKOTA * notice, this list of conditions and the following disclaimer in the 13559e7c1bSKazutaka YOKOTA * documentation and/or other materials provided with the distribution. 14559e7c1bSKazutaka YOKOTA * 15559e7c1bSKazutaka YOKOTA * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16559e7c1bSKazutaka YOKOTA * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17559e7c1bSKazutaka YOKOTA * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18559e7c1bSKazutaka YOKOTA * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19559e7c1bSKazutaka YOKOTA * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20559e7c1bSKazutaka YOKOTA * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21559e7c1bSKazutaka YOKOTA * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22559e7c1bSKazutaka YOKOTA * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23559e7c1bSKazutaka YOKOTA * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24559e7c1bSKazutaka YOKOTA * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25559e7c1bSKazutaka YOKOTA * 2611b5621eSKazutaka YOKOTA * $Id: splash.c,v 1.2 1999/01/11 03:06:28 yokota Exp $ 27617b9080SKazutaka YOKOTA */ 28617b9080SKazutaka YOKOTA 29617b9080SKazutaka YOKOTA #include "splash.h" 30617b9080SKazutaka YOKOTA 31617b9080SKazutaka YOKOTA #if NSPLASH > 0 32617b9080SKazutaka YOKOTA 33617b9080SKazutaka YOKOTA #include <sys/param.h> 34617b9080SKazutaka YOKOTA #include <sys/systm.h> 35617b9080SKazutaka YOKOTA #include <sys/kernel.h> 36617b9080SKazutaka YOKOTA #include <sys/malloc.h> 37617b9080SKazutaka YOKOTA #include <sys/linker.h> 38617b9080SKazutaka YOKOTA 39617b9080SKazutaka YOKOTA #include <machine/console.h> 40617b9080SKazutaka YOKOTA 41617b9080SKazutaka YOKOTA #include <dev/fb/fbreg.h> 42617b9080SKazutaka YOKOTA #include <dev/fb/splashreg.h> 43617b9080SKazutaka YOKOTA 44617b9080SKazutaka YOKOTA /* video adapter and image decoder */ 45617b9080SKazutaka YOKOTA static video_adapter_t *splash_adp; 46617b9080SKazutaka YOKOTA static splash_decoder_t *splash_decoder; 47617b9080SKazutaka YOKOTA 48617b9080SKazutaka YOKOTA /* decoder candidates */ 49617b9080SKazutaka YOKOTA static int decoders; 50617b9080SKazutaka YOKOTA static splash_decoder_t **decoder_set; 51617b9080SKazutaka YOKOTA #define DECODER_ARRAY_DELTA 4 52617b9080SKazutaka YOKOTA 53617b9080SKazutaka YOKOTA /* console driver callback */ 54617b9080SKazutaka YOKOTA static int (*splash_callback)(int); 55617b9080SKazutaka YOKOTA 56617b9080SKazutaka YOKOTA static int 57559e7c1bSKazutaka YOKOTA splash_find_data(splash_decoder_t *decoder) 58617b9080SKazutaka YOKOTA { 59617b9080SKazutaka YOKOTA caddr_t image_module; 60617b9080SKazutaka YOKOTA caddr_t p; 61617b9080SKazutaka YOKOTA 62559e7c1bSKazutaka YOKOTA if (decoder->data_type == NULL) 63559e7c1bSKazutaka YOKOTA return 0; 64559e7c1bSKazutaka YOKOTA image_module = preload_search_by_type(decoder->data_type); 65617b9080SKazutaka YOKOTA if (image_module == NULL) 66617b9080SKazutaka YOKOTA return ENOENT; 67617b9080SKazutaka YOKOTA p = preload_search_info(image_module, MODINFO_ADDR); 68617b9080SKazutaka YOKOTA if (p == NULL) 69617b9080SKazutaka YOKOTA return ENOENT; 70559e7c1bSKazutaka YOKOTA decoder->data = *(void **)p; 71617b9080SKazutaka YOKOTA p = preload_search_info(image_module, MODINFO_SIZE); 72617b9080SKazutaka YOKOTA if (p == NULL) 73617b9080SKazutaka YOKOTA return ENOENT; 74559e7c1bSKazutaka YOKOTA decoder->data_size = *(size_t *)p; 75559e7c1bSKazutaka YOKOTA if (bootverbose) 76559e7c1bSKazutaka YOKOTA printf("splash: image@%p, size:%u\n", 77559e7c1bSKazutaka YOKOTA decoder->data, decoder->data_size); 78617b9080SKazutaka YOKOTA return 0; 79617b9080SKazutaka YOKOTA } 80617b9080SKazutaka YOKOTA 81617b9080SKazutaka YOKOTA static int 82617b9080SKazutaka YOKOTA splash_test(splash_decoder_t *decoder) 83617b9080SKazutaka YOKOTA { 84559e7c1bSKazutaka YOKOTA if (splash_find_data(decoder)) 85559e7c1bSKazutaka YOKOTA return ENOENT; /* XXX */ 86559e7c1bSKazutaka YOKOTA if ((*decoder->init)(splash_adp)) { 87559e7c1bSKazutaka YOKOTA decoder->data = NULL; 88559e7c1bSKazutaka YOKOTA decoder->data_size = 0; 89617b9080SKazutaka YOKOTA return ENODEV; /* XXX */ 90559e7c1bSKazutaka YOKOTA } 91617b9080SKazutaka YOKOTA if (bootverbose) 92617b9080SKazutaka YOKOTA printf("splash: image decoder found: %s\n", decoder->name); 93559e7c1bSKazutaka YOKOTA return 0; 94559e7c1bSKazutaka YOKOTA } 95559e7c1bSKazutaka YOKOTA 96559e7c1bSKazutaka YOKOTA static void 97559e7c1bSKazutaka YOKOTA splash_new(splash_decoder_t *decoder) 98559e7c1bSKazutaka YOKOTA { 99617b9080SKazutaka YOKOTA splash_decoder = decoder; 100617b9080SKazutaka YOKOTA if (splash_callback != NULL) 101617b9080SKazutaka YOKOTA (*splash_callback)(SPLASH_INIT); 102617b9080SKazutaka YOKOTA } 103617b9080SKazutaka YOKOTA 104617b9080SKazutaka YOKOTA int 105617b9080SKazutaka YOKOTA splash_register(splash_decoder_t *decoder) 106617b9080SKazutaka YOKOTA { 107617b9080SKazutaka YOKOTA splash_decoder_t **p; 108559e7c1bSKazutaka YOKOTA int error; 109617b9080SKazutaka YOKOTA int i; 110617b9080SKazutaka YOKOTA 111559e7c1bSKazutaka YOKOTA if (splash_adp != NULL) { 112617b9080SKazutaka YOKOTA /* 113559e7c1bSKazutaka YOKOTA * If the video card has aleady been initialized, test 114559e7c1bSKazutaka YOKOTA * this decoder immediately. 115617b9080SKazutaka YOKOTA */ 116559e7c1bSKazutaka YOKOTA error = splash_test(decoder); 117559e7c1bSKazutaka YOKOTA if (error == 0) { 118559e7c1bSKazutaka YOKOTA /* replace the current decoder with new one */ 119559e7c1bSKazutaka YOKOTA if (splash_decoder != NULL) 120559e7c1bSKazutaka YOKOTA error = splash_term(splash_adp); 121559e7c1bSKazutaka YOKOTA if (error == 0) 122559e7c1bSKazutaka YOKOTA splash_new(decoder); 123559e7c1bSKazutaka YOKOTA } 124559e7c1bSKazutaka YOKOTA return error; 125559e7c1bSKazutaka YOKOTA } else { 126617b9080SKazutaka YOKOTA /* register the decoder for later use */ 127617b9080SKazutaka YOKOTA for (i = 0; i < decoders; ++i) { 128617b9080SKazutaka YOKOTA if (decoder_set[i] == NULL) 129617b9080SKazutaka YOKOTA break; 130617b9080SKazutaka YOKOTA } 131617b9080SKazutaka YOKOTA if ((i >= decoders) && (decoders % DECODER_ARRAY_DELTA) == 0) { 132617b9080SKazutaka YOKOTA p = malloc(sizeof(*p)*(decoders + DECODER_ARRAY_DELTA), 133617b9080SKazutaka YOKOTA M_DEVBUF, M_NOWAIT); 134617b9080SKazutaka YOKOTA if (p == NULL) 135617b9080SKazutaka YOKOTA return ENOMEM; 13611b5621eSKazutaka YOKOTA if (decoder_set != NULL) { 137617b9080SKazutaka YOKOTA bcopy(decoder_set, p, sizeof(*p)*decoders); 138617b9080SKazutaka YOKOTA free(decoder_set, M_DEVBUF); 13911b5621eSKazutaka YOKOTA } 140617b9080SKazutaka YOKOTA decoder_set = p; 141617b9080SKazutaka YOKOTA i = decoders++; 142617b9080SKazutaka YOKOTA } 143617b9080SKazutaka YOKOTA decoder_set[i] = decoder; 144559e7c1bSKazutaka YOKOTA } 145559e7c1bSKazutaka YOKOTA 146617b9080SKazutaka YOKOTA return 0; 147617b9080SKazutaka YOKOTA } 148617b9080SKazutaka YOKOTA 149617b9080SKazutaka YOKOTA int 150617b9080SKazutaka YOKOTA splash_unregister(splash_decoder_t *decoder) 151617b9080SKazutaka YOKOTA { 152617b9080SKazutaka YOKOTA int error; 153617b9080SKazutaka YOKOTA 154617b9080SKazutaka YOKOTA if (splash_decoder == decoder) { 155617b9080SKazutaka YOKOTA if ((error = splash_term(splash_adp)) != 0) 156617b9080SKazutaka YOKOTA return error; 157617b9080SKazutaka YOKOTA } 158617b9080SKazutaka YOKOTA return 0; 159617b9080SKazutaka YOKOTA } 160617b9080SKazutaka YOKOTA 161617b9080SKazutaka YOKOTA int 162617b9080SKazutaka YOKOTA splash_init(video_adapter_t *adp, int (*callback)(int)) 163617b9080SKazutaka YOKOTA { 164617b9080SKazutaka YOKOTA int i; 165617b9080SKazutaka YOKOTA 166617b9080SKazutaka YOKOTA splash_adp = adp; 167617b9080SKazutaka YOKOTA splash_callback = callback; 168617b9080SKazutaka YOKOTA 169617b9080SKazutaka YOKOTA splash_decoder = NULL; 170617b9080SKazutaka YOKOTA for (i = 0; i < decoders; ++i) { 171617b9080SKazutaka YOKOTA if (decoder_set[i] == NULL) 172617b9080SKazutaka YOKOTA continue; 173559e7c1bSKazutaka YOKOTA if (splash_test(decoder_set[i]) == 0) { 174559e7c1bSKazutaka YOKOTA splash_new(decoder_set[i]); 175617b9080SKazutaka YOKOTA break; 176617b9080SKazutaka YOKOTA } 177559e7c1bSKazutaka YOKOTA decoder_set[i] = NULL; 178559e7c1bSKazutaka YOKOTA } 179559e7c1bSKazutaka YOKOTA for (++i; i < decoders; ++i) { 180559e7c1bSKazutaka YOKOTA decoder_set[i] = NULL; 181559e7c1bSKazutaka YOKOTA } 182617b9080SKazutaka YOKOTA return 0; 183617b9080SKazutaka YOKOTA } 184617b9080SKazutaka YOKOTA 185617b9080SKazutaka YOKOTA int 186617b9080SKazutaka YOKOTA splash_term(video_adapter_t *adp) 187617b9080SKazutaka YOKOTA { 188617b9080SKazutaka YOKOTA int error = 0; 189617b9080SKazutaka YOKOTA 190617b9080SKazutaka YOKOTA if (splash_decoder != NULL) { 191617b9080SKazutaka YOKOTA if (splash_callback != NULL) 192617b9080SKazutaka YOKOTA error = (*splash_callback)(SPLASH_TERM); 193617b9080SKazutaka YOKOTA if (error == 0) 194617b9080SKazutaka YOKOTA error = (*splash_decoder->term)(adp); 195617b9080SKazutaka YOKOTA if (error == 0) 196617b9080SKazutaka YOKOTA splash_decoder = NULL; 197617b9080SKazutaka YOKOTA } 198617b9080SKazutaka YOKOTA return error; 199617b9080SKazutaka YOKOTA } 200617b9080SKazutaka YOKOTA 201617b9080SKazutaka YOKOTA int 202617b9080SKazutaka YOKOTA splash(video_adapter_t *adp, int on) 203617b9080SKazutaka YOKOTA { 204617b9080SKazutaka YOKOTA if (splash_decoder != NULL) 205617b9080SKazutaka YOKOTA return (*splash_decoder->splash)(adp, on); 206617b9080SKazutaka YOKOTA return ENODEV; 207617b9080SKazutaka YOKOTA } 208617b9080SKazutaka YOKOTA 209617b9080SKazutaka YOKOTA #endif /* NSPLASH > 0 */ 210