@@ -133,13 +133,11 @@ void efi_parse_option_graphics(char *option)
133
133
134
134
static u32 choose_mode_modenum (efi_graphics_output_protocol_t * gop )
135
135
{
136
- efi_status_t status ;
137
-
136
+ efi_graphics_output_mode_info_t * info __free (efi_pool ) = NULL ;
138
137
efi_graphics_output_protocol_mode_t * mode ;
139
- efi_graphics_output_mode_info_t * info ;
140
138
unsigned long info_size ;
141
-
142
139
u32 max_mode , cur_mode ;
140
+ efi_status_t status ;
143
141
int pf ;
144
142
145
143
mode = efi_table_attr (gop , mode );
@@ -154,17 +152,13 @@ static u32 choose_mode_modenum(efi_graphics_output_protocol_t *gop)
154
152
return cur_mode ;
155
153
}
156
154
157
- status = efi_call_proto (gop , query_mode , cmdline .mode ,
158
- & info_size , & info );
155
+ status = efi_call_proto (gop , query_mode , cmdline .mode , & info_size , & info );
159
156
if (status != EFI_SUCCESS ) {
160
157
efi_err ("Couldn't get mode information\n" );
161
158
return cur_mode ;
162
159
}
163
160
164
161
pf = info -> pixel_format ;
165
-
166
- efi_bs_call (free_pool , info );
167
-
168
162
if (pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX ) {
169
163
efi_err ("Invalid PixelFormat\n" );
170
164
return cur_mode ;
@@ -173,6 +167,28 @@ static u32 choose_mode_modenum(efi_graphics_output_protocol_t *gop)
173
167
return cmdline .mode ;
174
168
}
175
169
170
+ static u32 choose_mode (efi_graphics_output_protocol_t * gop ,
171
+ bool (* match )(const efi_graphics_output_mode_info_t * , u32 , void * ),
172
+ void * ctx )
173
+ {
174
+ efi_graphics_output_protocol_mode_t * mode = efi_table_attr (gop , mode );
175
+ u32 max_mode = efi_table_attr (mode , max_mode );
176
+
177
+ for (u32 m = 0 ; m < max_mode ; m ++ ) {
178
+ efi_graphics_output_mode_info_t * info __free (efi_pool ) = NULL ;
179
+ unsigned long info_size ;
180
+ efi_status_t status ;
181
+
182
+ status = efi_call_proto (gop , query_mode , m , & info_size , & info );
183
+ if (status != EFI_SUCCESS )
184
+ continue ;
185
+
186
+ if (match (info , m , ctx ))
187
+ return m ;
188
+ }
189
+ return (unsigned long )ctx ;
190
+ }
191
+
176
192
static u8 pixel_bpp (int pixel_format , efi_pixel_bitmask_t pixel_info )
177
193
{
178
194
if (pixel_format == PIXEL_BIT_MASK ) {
@@ -185,192 +201,117 @@ static u8 pixel_bpp(int pixel_format, efi_pixel_bitmask_t pixel_info)
185
201
return 32 ;
186
202
}
187
203
188
- static u32 choose_mode_res ( efi_graphics_output_protocol_t * gop )
204
+ static bool match_res ( const efi_graphics_output_mode_info_t * info , u32 mode , void * ctx )
189
205
{
190
- efi_status_t status ;
206
+ efi_pixel_bitmask_t pi = info -> pixel_information ;
207
+ int pf = info -> pixel_format ;
191
208
192
- efi_graphics_output_protocol_mode_t * mode ;
193
- efi_graphics_output_mode_info_t * info ;
194
- unsigned long info_size ;
195
-
196
- u32 max_mode , cur_mode ;
197
- int pf ;
198
- efi_pixel_bitmask_t pi ;
199
- u32 m , w , h ;
209
+ if (pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX )
210
+ return false;
200
211
201
- mode = efi_table_attr (gop , mode );
212
+ return cmdline .res .width == info -> horizontal_resolution &&
213
+ cmdline .res .height == info -> vertical_resolution &&
214
+ (cmdline .res .format < 0 || cmdline .res .format == pf ) &&
215
+ (!cmdline .res .depth || cmdline .res .depth == pixel_bpp (pf , pi ));
216
+ }
202
217
203
- cur_mode = efi_table_attr (mode , mode );
204
- info = efi_table_attr (mode , info );
205
- pf = info -> pixel_format ;
206
- pi = info -> pixel_information ;
207
- w = info -> horizontal_resolution ;
208
- h = info -> vertical_resolution ;
218
+ static u32 choose_mode_res (efi_graphics_output_protocol_t * gop )
219
+ {
220
+ efi_graphics_output_protocol_mode_t * mode = efi_table_attr (gop , mode );
221
+ unsigned long cur_mode = efi_table_attr (mode , mode );
209
222
210
- if (w == cmdline .res .width && h == cmdline .res .height &&
211
- (cmdline .res .format < 0 || cmdline .res .format == pf ) &&
212
- (!cmdline .res .depth || cmdline .res .depth == pixel_bpp (pf , pi )))
223
+ if (match_res (efi_table_attr (mode , info ), cur_mode , NULL ))
213
224
return cur_mode ;
214
225
215
- max_mode = efi_table_attr (mode , max_mode );
216
-
217
- for (m = 0 ; m < max_mode ; m ++ ) {
218
- if (m == cur_mode )
219
- continue ;
220
-
221
- status = efi_call_proto (gop , query_mode , m ,
222
- & info_size , & info );
223
- if (status != EFI_SUCCESS )
224
- continue ;
226
+ return choose_mode (gop , match_res , (void * )cur_mode );
227
+ }
225
228
226
- pf = info -> pixel_format ;
227
- pi = info -> pixel_information ;
228
- w = info -> horizontal_resolution ;
229
- h = info -> vertical_resolution ;
229
+ struct match {
230
+ u32 mode ;
231
+ u32 area ;
232
+ u8 depth ;
233
+ };
230
234
231
- efi_bs_call (free_pool , info );
235
+ static bool match_auto (const efi_graphics_output_mode_info_t * info , u32 mode , void * ctx )
236
+ {
237
+ u32 area = info -> horizontal_resolution * info -> vertical_resolution ;
238
+ efi_pixel_bitmask_t pi = info -> pixel_information ;
239
+ int pf = info -> pixel_format ;
240
+ u8 depth = pixel_bpp (pf , pi );
241
+ struct match * m = ctx ;
232
242
233
- if (pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX )
234
- continue ;
235
- if (w == cmdline .res .width && h == cmdline .res .height &&
236
- (cmdline .res .format < 0 || cmdline .res .format == pf ) &&
237
- (!cmdline .res .depth || cmdline .res .depth == pixel_bpp (pf , pi )))
238
- return m ;
239
- }
243
+ if (pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX )
244
+ return false;
240
245
241
- efi_err ("Couldn't find requested mode\n" );
246
+ if (area > m -> area || (area == m -> area && depth > m -> depth ))
247
+ * m = (struct match ){ mode , area , depth };
242
248
243
- return cur_mode ;
249
+ return false ;
244
250
}
245
251
246
252
static u32 choose_mode_auto (efi_graphics_output_protocol_t * gop )
247
253
{
248
- efi_status_t status ;
254
+ struct match match = {} ;
249
255
250
- efi_graphics_output_protocol_mode_t * mode ;
251
- efi_graphics_output_mode_info_t * info ;
252
- unsigned long info_size ;
256
+ choose_mode (gop , match_auto , & match );
253
257
254
- u32 max_mode , cur_mode , best_mode , area ;
255
- u8 depth ;
256
- int pf ;
257
- efi_pixel_bitmask_t pi ;
258
- u32 m , w , h , a ;
259
- u8 d ;
260
-
261
- mode = efi_table_attr (gop , mode );
262
-
263
- cur_mode = efi_table_attr (mode , mode );
264
- max_mode = efi_table_attr (mode , max_mode );
265
-
266
- info = efi_table_attr (mode , info );
267
-
268
- pf = info -> pixel_format ;
269
- pi = info -> pixel_information ;
270
- w = info -> horizontal_resolution ;
271
- h = info -> vertical_resolution ;
272
-
273
- best_mode = cur_mode ;
274
- area = w * h ;
275
- depth = pixel_bpp (pf , pi );
276
-
277
- for (m = 0 ; m < max_mode ; m ++ ) {
278
- if (m == cur_mode )
279
- continue ;
280
-
281
- status = efi_call_proto (gop , query_mode , m ,
282
- & info_size , & info );
283
- if (status != EFI_SUCCESS )
284
- continue ;
258
+ return match .mode ;
259
+ }
285
260
286
- pf = info -> pixel_format ;
287
- pi = info -> pixel_information ;
288
- w = info -> horizontal_resolution ;
289
- h = info -> vertical_resolution ;
261
+ static bool match_list (const efi_graphics_output_mode_info_t * info , u32 mode , void * ctx )
262
+ {
263
+ efi_pixel_bitmask_t pi = info -> pixel_information ;
264
+ u32 cur_mode = (unsigned long )ctx ;
265
+ int pf = info -> pixel_format ;
266
+ const char * dstr ;
267
+ u8 depth = 0 ;
268
+ bool valid ;
290
269
291
- efi_bs_call ( free_pool , info );
270
+ valid = !( pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX );
292
271
293
- if (pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX )
294
- continue ;
295
- a = w * h ;
296
- if (a < area )
297
- continue ;
298
- d = pixel_bpp (pf , pi );
299
- if (a > area || d > depth ) {
300
- best_mode = m ;
301
- area = a ;
302
- depth = d ;
303
- }
272
+ switch (pf ) {
273
+ case PIXEL_RGB_RESERVED_8BIT_PER_COLOR :
274
+ dstr = "rgb" ;
275
+ break ;
276
+ case PIXEL_BGR_RESERVED_8BIT_PER_COLOR :
277
+ dstr = "bgr" ;
278
+ break ;
279
+ case PIXEL_BIT_MASK :
280
+ dstr = "" ;
281
+ depth = pixel_bpp (pf , pi );
282
+ break ;
283
+ case PIXEL_BLT_ONLY :
284
+ dstr = "blt" ;
285
+ break ;
286
+ default :
287
+ dstr = "xxx" ;
288
+ break ;
304
289
}
305
290
306
- return best_mode ;
291
+ efi_printk ("Mode %3u %c%c: Resolution %ux%u-%s%.0hhu\n" ,
292
+ mode ,
293
+ (mode == cur_mode ) ? '*' : ' ' ,
294
+ !valid ? '-' : ' ' ,
295
+ info -> horizontal_resolution ,
296
+ info -> vertical_resolution ,
297
+ dstr , depth );
298
+
299
+ return false;
307
300
}
308
301
309
302
static u32 choose_mode_list (efi_graphics_output_protocol_t * gop )
310
303
{
311
- efi_status_t status ;
312
-
313
- efi_graphics_output_protocol_mode_t * mode ;
314
- efi_graphics_output_mode_info_t * info ;
315
- unsigned long info_size ;
316
-
317
- u32 max_mode , cur_mode ;
318
- int pf ;
319
- efi_pixel_bitmask_t pi ;
320
- u32 m , w , h ;
321
- u8 d ;
322
- const char * dstr ;
323
- bool valid ;
304
+ efi_graphics_output_protocol_mode_t * mode = efi_table_attr (gop , mode );
305
+ unsigned long cur_mode = efi_table_attr (mode , mode );
306
+ u32 max_mode = efi_table_attr (mode , max_mode );
324
307
efi_input_key_t key ;
325
-
326
- mode = efi_table_attr (gop , mode );
327
-
328
- cur_mode = efi_table_attr (mode , mode );
329
- max_mode = efi_table_attr (mode , max_mode );
308
+ efi_status_t status ;
330
309
331
310
efi_printk ("Available graphics modes are 0-%u\n" , max_mode - 1 );
332
311
efi_puts (" * = current mode\n"
333
312
" - = unusable mode\n" );
334
- for (m = 0 ; m < max_mode ; m ++ ) {
335
- status = efi_call_proto (gop , query_mode , m ,
336
- & info_size , & info );
337
- if (status != EFI_SUCCESS )
338
- continue ;
339
313
340
- pf = info -> pixel_format ;
341
- pi = info -> pixel_information ;
342
- w = info -> horizontal_resolution ;
343
- h = info -> vertical_resolution ;
344
-
345
- efi_bs_call (free_pool , info );
346
-
347
- valid = !(pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX );
348
- d = 0 ;
349
- switch (pf ) {
350
- case PIXEL_RGB_RESERVED_8BIT_PER_COLOR :
351
- dstr = "rgb" ;
352
- break ;
353
- case PIXEL_BGR_RESERVED_8BIT_PER_COLOR :
354
- dstr = "bgr" ;
355
- break ;
356
- case PIXEL_BIT_MASK :
357
- dstr = "" ;
358
- d = pixel_bpp (pf , pi );
359
- break ;
360
- case PIXEL_BLT_ONLY :
361
- dstr = "blt" ;
362
- break ;
363
- default :
364
- dstr = "xxx" ;
365
- break ;
366
- }
367
-
368
- efi_printk ("Mode %3u %c%c: Resolution %ux%u-%s%.0hhu\n" ,
369
- m ,
370
- m == cur_mode ? '*' : ' ' ,
371
- !valid ? '-' : ' ' ,
372
- w , h , dstr , d );
373
- }
314
+ choose_mode (gop , match_list , (void * )cur_mode );
374
315
375
316
efi_puts ("\nPress any key to continue (or wait 10 seconds)\n" );
376
317
status = efi_wait_for_key (10 * EFI_USEC_PER_SEC , & key );
0 commit comments