Trust uboot's device list only if it does not look suspicious.
[AROS.git] / arch / all-pc / bootstrap / vesa_setup.c
blobe305a989555d3d100b747f541593a71e7dd0e7b2
1 #define DEBUG
3 #include <aros/kernel.h>
4 #include <hardware/vbe.h>
6 #include <bootconsole.h>
7 #include <stdlib.h>
8 #include <string.h>
10 #include "bootstrap.h"
11 #include "support.h"
12 #include "vesa.h"
14 void setupVESA(char *vesa)
16 short r;
17 unsigned char palwidth = 6;
18 BOOL prioritise_depth = FALSE, set_refresh = FALSE;
19 long x = 0, y = 0, d = 0, vfreq = 0;
20 long mode;
21 unsigned long vesa_size = (unsigned long)&_binary_vesa_size;
22 void *vesa_start = &_binary_vesa_start;
23 void *tmp = __bs_malloc(vesa_size);
25 if (!tmp)
27 kprintf("[VESA] Setup failed, not enough working memory\n");
28 return;
31 x = strtoul(vesa, &vesa, 10);
32 if (*vesa == 'x')
34 vesa++;
35 y = strtoul(vesa, &vesa, 10);
37 if (*vesa == 'x')
39 vesa++;
40 d = strtoul(vesa, &vesa, 10);
42 else
43 d = 32;
45 else
46 d = x, x = 10000, y = 10000, prioritise_depth = TRUE;
48 /* Check for user-set refresh rate */
49 if (*vesa == '@')
51 vesa++;
52 vfreq = strtoul(vesa, &vesa, 10);
53 set_refresh = TRUE;
55 else
56 vfreq = 60;
59 * 16-bit VBE trampoline is needed only once only here, so
60 * we can simply copy it to some address, do what we need, and
61 * then forget.
62 * However we must keep in mind that low memory can be occupied by
63 * something useful, like kickstart modules or boot information.
64 * So we preserve our region and put it back when we are done.
66 D(kprintf("[VESA] Backing up low memory, buffer at 0x%p\n", tmp));
67 memcpy(tmp, VESA_START, vesa_size);
69 D(kprintf("[VESA] vesa.bin @ %p [size=%d]\n", &_binary_vesa_start, &_binary_vesa_size));
70 memcpy(VESA_START, vesa_start, vesa_size);
72 kprintf("[VESA] BestModeMatch for %ldx%ldx%ld = ", x, y, d);
73 mode = findMode(x, y, d, vfreq, prioritise_depth);
75 /* Get information and copy it from 16-bit memory space to our 32-bit memory */
76 getModeInfo(mode);
77 memcpy(&VBEModeInfo, modeinfo, sizeof(struct vbe_mode));
78 getControllerInfo();
79 memcpy(&VBEControllerInfo, controllerinfo, sizeof(struct vbe_controller));
81 /* Activate linear framebuffer is supported by the mode */
82 if (VBEModeInfo.mode_attributes & VM_LINEAR_FB)
83 mode |= VBE_MODE_LINEAR_FB;
85 kprintf("%x\n",mode);
87 r = setVbeMode(mode, set_refresh);
88 if (r == VBE_RC_SUPPORTED)
90 /* Try to switch palette width to 8 bits if possible */
91 if (VBEControllerInfo.capabilities & VC_PALETTE_WIDTH)
92 paletteWidth(0x0800, &palwidth);
95 /* Put memory back and reset memory allocator */
96 memcpy(VESA_START, tmp, vesa_size);
97 __bs_free();
99 if (r == VBE_RC_SUPPORTED)
101 /* Reinitialize our console */
102 fb_Mirror = __bs_malloc(0);
103 con_InitVESA(VBEControllerInfo.version, &VBEModeInfo);
104 AllocFB();
106 D(kprintf("[VESA] VBE version 0x%04X\n", VBEControllerInfo.version));
107 D(kprintf("[VESA] Resolution %d x %d\n", VBEModeInfo.x_resolution, VBEModeInfo.y_resolution));
108 D(kprintf("[VESA] %d bits per pixel, %d/%d bytes per line\n", VBEModeInfo.bits_per_pixel, VBEModeInfo.bytes_per_scanline, VBEModeInfo.linear_bytes_per_scanline));
109 D(kprintf("[VESA] Mode flags 0x%04X, framebuffer 0x%p\n", VBEModeInfo.mode_attributes, VBEModeInfo.phys_base));
110 D(kprintf("[VESA] Windows A 0x%04X B 0x%04X\n", VBEModeInfo.win_a_segment, VBEModeInfo.win_b_segment));
112 tag->ti_Tag = KRN_VBEModeInfo;
113 tag->ti_Data = KERNEL_OFFSET | (unsigned long)&VBEModeInfo;
114 tag++;
116 tag->ti_Tag = KRN_VBEControllerInfo;
117 tag->ti_Data = KERNEL_OFFSET | (unsigned long)&VBEControllerInfo;
118 tag++;
120 tag->ti_Tag = KRN_VBEMode;
121 tag->ti_Data = mode;
122 tag++;
124 tag->ti_Tag = KRN_VBEPaletteWidth;
125 tag->ti_Data = palwidth;
126 tag++;
129 kprintf("[VESA] Setup complete\n");