Imported Debian patch 3.4-9
[debian/elilo] / elilo.c
1 /* 
2  * elilo.c - IA-64/IA-32 EFI Linux loader
3  *
4  *  Copyright (C) 1999-2003 Hewlett-Packard Co.
5  *      Contributed by David Mosberger <davidm@hpl.hp.com>.
6  *      Contributed by Stephane Eranian <eranian@hpl.hp.com>
7  *
8  *  Copyright (C) 1999-2000 VA Linux Systems
9  *       Contributed by Johannes Erdfelt <jerdfelt@valinux.com>.
10  *
11  * This file is part of the ELILO, the EFI Linux boot loader.
12  *
13  *  ELILO is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2, or (at your option)
16  *  any later version.
17  *
18  *  ELILO is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with ELILO; see the file COPYING.  If not, write to the Free
25  *  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26  *  02111-1307, USA.
27  *
28  * Please check out the elilo.txt for complete documentation on how
29  * to use this program.
30  */
31
32 #include <efi.h>
33 #include <efilib.h>
34
35 #include "elilo.h"
36 #include "vars.h"
37
38 #include "getopt.h"
39 #include "fileops.h"
40 #include "loader.h"
41 #include "config.h" /* for config_init() */
42
43 #define ELILO_VERSION                   L"3.4"
44 #define ELILO_SHARED_CMDLINE_OPTS       L"pPMC:aDhd:i:vVc:E"
45
46 elilo_config_t elilo_opt;
47
48 EFI_SYSTEM_TABLE *systab;       /* pointer to EFI system table */
49
50 /*
51  * Load the Linux kernel in memory from the boot media
52  * Output:
53  *      kd = address of kernel entry point
54  *         + end address of kernel code+data+bss
55  *         + kernel entry point
56  * Return:
57  *      ELILO_LOAD_ERROR   : if something went wrong
58  *      ELILO_LOAD_ABORTED : user interruption while loading
59  *      ELILO_LOAD_SUCCESS : otherwise
60  */
61 static INTN
62 do_kernel_load(CHAR16 *kname, kdesc_t *kd)
63 {
64         loader_ops_t    *ldops;
65         EFI_STATUS status;
66         fops_fd_t fd;
67
68         status = fops_open(kname, &fd);
69         if (EFI_ERROR(status)) {
70                 ERR_PRT((L"Kernel file  not found %s", kname));
71                 return ELILO_LOAD_ERROR;
72         }
73         fops_close(fd);
74
75         ldops = loader_probe(kname);
76         if (ldops == NULL) {
77                 ERR_PRT((L"Cannot find a loader for %s", kname));
78                 return ELILO_LOAD_ERROR;
79         }
80
81         VERB_PRT(1,Print(L"Using %s loader\n", ldops->ld_name));
82         
83         return ldops->ld_load_kernel(kname, kd);
84 }
85
86 INTN
87 kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem)
88 {
89
90         /*
91          * Now let's try to load the kernel !
92          */
93         switch(do_kernel_load(kname, kd)) {
94                 case ELILO_LOAD_SUCCESS:
95                         break;
96
97                 case ELILO_LOAD_ERROR:
98                         /* XXX: add fallback support */
99                         return ELILO_LOAD_ERROR;
100                 
101                 case ELILO_LOAD_ABORTED:
102                         /* we drop initrd in case we aborted the load */
103                         elilo_opt.initrd[0] = CHAR_NULL;
104
105                         /* will go back to interactive selection */
106                         elilo_opt.prompt  = 1; 
107                         elilo_opt.timeout = ELILO_DEFAULT_TIMEOUT;
108                         elilo_opt.delay   = 0;
109
110                         return ELILO_LOAD_RETRY;        
111         }
112
113         VERB_PRT(3, Print(L"kernel loaded in [0x%lx-0x%lx] entry=0x%lx\n", 
114                           (UINT64)kd->kstart, (UINT64)kd->kend, (UINT64)kd->kentry));
115
116         if (elilo_opt.initrd[0]) {
117
118                 if (sysdeps_initrd_get_addr(kd, imem) == -1) goto exit_error;
119
120                 switch(load_initrd(elilo_opt.initrd, imem)) {
121                         case ELILO_LOAD_SUCCESS:
122                                 break;
123                         case ELILO_LOAD_ERROR:
124                                 goto exit_error;
125                         case ELILO_LOAD_ABORTED:
126                                 /* the free_kmem() is the responsibility of the loader */
127
128                                 /* we drop initrd in case we aborted the load */
129                                 elilo_opt.initrd[0] = CHAR_NULL;
130                                 elilo_opt.prompt    = 1; 
131                                 elilo_opt.timeout   = ELILO_DEFAULT_TIMEOUT;
132                                 elilo_opt.delay     = 0;
133
134                                 return ELILO_LOAD_RETRY;
135                 }
136         }
137         return ELILO_LOAD_SUCCESS;
138 exit_error:
139         free_kmem();
140         if (imem->start_addr) free(imem->start_addr);
141
142         return ELILO_LOAD_ERROR;
143 }
144
145 static INTN
146 main_loop(EFI_HANDLE dev, CHAR16 **argv, INTN argc, INTN index, EFI_HANDLE image)
147 {
148         CHAR16 kname[FILENAME_MAXLEN];
149         CHAR16 cmdline_tmp[CMDLINE_MAXLEN];
150         CHAR16 cmdline[CMDLINE_MAXLEN];
151         VOID *bp;
152         UINTN cookie;
153         EFI_STATUS status = EFI_SUCCESS;
154         kdesc_t kd;
155         memdesc_t imem;
156         INTN r;
157
158         /*
159          * First place where we potentially do system dependent
160          * operations. It is a one time opportunity before entering
161          * the main loop
162          */
163         if (sysdeps_preloop_actions(dev, argv, argc, index, image) == -1) return -1;
164
165         for(;;) {
166                 kname[0] = cmdline_tmp[0] = cmdline[0] = CHAR_NULL;
167                 imem.start_addr = 0; imem.pgcnt = 0;
168                 elilo_opt.sys_img_opts = NULL;
169
170                 if (kernel_chooser(argv, argc, index, kname, cmdline_tmp) == -1) goto exit_error;
171
172                 switch (kernel_load(image, kname, &kd, &imem)) {
173                         case ELILO_LOAD_SUCCESS: 
174                                 goto do_launch;
175                         case ELILO_LOAD_ERROR:
176                                 goto exit_error;
177                         /* otherwise we retry ! */
178                 }
179         } 
180
181 do_launch:
182         r =subst_vars(cmdline_tmp, cmdline, CMDLINE_MAXLEN);
183
184         VERB_PRT(3, Print(L"final cmdline(%d): %s\n", r, cmdline));
185
186         /* free resources associated with file accesses (before ExitBootServices) */
187         close_devices();
188
189         /* No console output permitted after create_boot_params()! */
190         if ((bp=create_boot_params(cmdline, &imem, &cookie)) == 0) goto error;
191
192         /* terminate bootservices */
193         status = BS->ExitBootServices(image, cookie);
194         if (EFI_ERROR(status)) goto bad_exit;
195
196         start_kernel(kd.kentry, bp);
197         /* NOT REACHED */
198
199         ERR_PRT((L"start_kernel() return !"));
200 bad_exit:       
201         /*
202          * we are still in BootService mode
203          */
204         ERR_PRT((L"ExitBootServices failed %r", status));
205 error:
206         free_kmem();
207         if (imem.start_addr) free(imem.start_addr);
208         if (bp) free_boot_params(bp);
209 exit_error:
210         return ELILO_LOAD_ERROR;
211
212 }
213
214 static VOID
215 elilo_help(VOID)
216 {
217         
218         Print(L"-d secs   timeout in 10th of second before booting\n");
219         Print(L"-h        this help text\n");
220         Print(L"-V        print version\n");
221         Print(L"-v        verbose level(can appear multiple times)\n");
222         Print(L"-a        always check for alternate kernel image\n");
223         Print(L"-i file   load file as the initial ramdisk\n");
224         Print(L"-C file   indicate the config file to use\n");
225         Print(L"-P        parse config file only (verify syntax)\n");
226         Print(L"-D        enable debug prints\n");
227         Print(L"-p        force interactive mode\n");
228         Print(L"-c name   image chooser to use\n");
229         Print(L"-E        do not force EDD30 variable\n");
230
231         sysdeps_print_cmdline_opts();
232
233         Print(L"\n");
234
235         print_config_options();
236 }
237
238 /*
239  * XXX: hack to work around a problem with EFI command line argument when booted
240  * from network. In this case, it looks like LoadOptions/LoadOptionsSize contain
241  * garbage
242  */
243 static CHAR16 *default_load_options;
244 static UINTN default_load_options_size;
245 static INTN done_fixups;
246
247 static VOID
248 fixupargs(EFI_LOADED_IMAGE *info)
249 {
250         EFI_STATUS status;
251         EFI_PXE_BASE_CODE *pxe;
252
253 #define FAKE_ELILONAME  L"elilo-forced"
254
255         status = BS->HandleProtocol (info->DeviceHandle, &PxeBaseCodeProtocol, (VOID **)&pxe);
256         if (EFI_ERROR(status)) return;
257
258         default_load_options      = info->LoadOptions;
259         default_load_options_size = info->LoadOptionsSize;
260
261         info->LoadOptions     = FAKE_ELILONAME;
262         info->LoadOptionsSize = StrLen(info->LoadOptions)*sizeof(CHAR16);
263
264         done_fixups = 1;
265 }
266
267 /*
268  * we restore the arguments in case we modified them just to make sure
269  * we don't confuse caller.
270  */
271 static VOID
272 unfixupargs(EFI_LOADED_IMAGE *info)
273 {
274         if (done_fixups == 0) return;
275
276         info->LoadOptions     = default_load_options;
277         info->LoadOptionsSize = default_load_options_size;
278 }
279
280
281 /*
282  * in order to get fully detailed EFI path names to devices, EDD3.0 specification must
283  * be turned on. On new versions of EFI, this is the default. An environment variable
284  * called EDD30 reflects the current settings. If true, then EDD3.0 is enabled 
285  * and device path names show the detailed device types. If false, then a default 
286  * generic name is used instead. This has some implications of ELILO's ability to 
287  * provide a better naming scheme for detected devices. If EDD3.0 is enabled
288  * then much more precise names can be used which makes it easy to use. 
289  * If EDD3.0 is nont enabled, ELILO will still work but will use very generic names
290  * for devices.
291  *
292  * ELILO will check the value of the variable. If not true, then it will force it to
293  * true. This will require a reboot for EFI to make use of the new value.
294  * Return:
295  *      EFI_SUCCESS: if variable is already true or was set to true
296  *      EFI error code: otherwise, like when could not forced variable or unrecognized variable content
297  */
298 #define EDD30_GUID \
299 {0x964e5b21, 0x6459, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}}
300
301 #define EDD30_ATTR (EFI_VARIABLE_RUNTIME_ACCESS|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_NON_VOLATILE)
302
303 static EFI_GUID edd30_guid = EDD30_GUID;
304
305 static INTN
306 check_edd30(VOID)
307 {
308         EFI_STATUS      status;
309         UINTN           l = sizeof(BOOLEAN);
310         UINT8           bool = FALSE;
311         INTN            ret = -1;
312
313         status = RT->GetVariable(L"EDD30", &edd30_guid, NULL, &l, &bool);
314         if (status == EFI_BUFFER_TOO_SMALL || (bool != TRUE && bool != FALSE)) {
315                 ERR_PRT((L"Warning: EDD30 EFI variable is not boolean value: forcing it to TRUE"));
316                 return -1;
317         }
318         if (status == EFI_SUCCESS && bool == TRUE) {
319                 VERB_PRT(3, Print(L"EDD30 is TRUE\n"));
320                 elilo_opt.edd30_on = TRUE;
321                 ret = 0;
322         } else {
323                 VERB_PRT(4, 
324                         if (status != EFI_SUCCESS) {
325                                 Print(L"EDD30 EFI variable not defined\n");
326                         } else {
327                                 Print(L"EDD30 EFI variable is false\n");
328                         }
329                 );
330         }
331
332         return ret;
333 }
334
335 static INTN
336 force_edd30(VOID)
337 {
338         EFI_STATUS      status;
339         UINTN           l = sizeof(BOOLEAN);
340         UINT8           bool;
341
342         bool = TRUE;
343         status = RT->SetVariable(L"EDD30", &edd30_guid, EDD30_ATTR, l, &bool);
344         if (EFI_ERROR(status)) {
345                 ERR_PRT((L"can't set EDD30 variable: ignoring it"));
346                 return -1;
347         }
348
349         VERB_PRT(3, Print(L"EDD30 variable forced to TRUE. You should reboot to take advantage of EDD3.0.\n"));
350
351         return 0;
352 }
353
354 /*
355  * That's equivalent of main(): main entry point
356  */
357 EFI_STATUS
358 efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab)
359 {
360         CHAR16 *argv[MAX_ARGS];
361         CHAR16 optstring[MAX_ARGS];
362         EFI_LOADED_IMAGE *info;
363         EFI_STATUS status, ret = EFI_LOAD_ERROR;
364         INTN argc = 0, c;
365         INTN edd30_status, retry;
366         CHAR16 *ptr, *arglist = NULL;
367         BOOLEAN devices_initialized = FALSE;
368         CHAR16 dpath[FILENAME_MAXLEN];
369         CHAR16 *devpath;
370
371         //elilo_opt.verbose=3;
372         //elilo_opt.debug=1;
373
374         /* initialize global variable */
375         systab = system_tab;
376         
377         /* initialize EFI library */
378         InitializeLib(image, systab);
379         /*
380          * disable the platform watchdog timer if we go interactive
381          * XXX: we should reinstate it once we're done
382          * It seems like with PXE, the timer is set to a few minutes
383          * and sometimes triggers if we stay too long in interactive
384          * mode.
385          * XXX: clean this up !
386          */
387        BS->SetWatchdogTimer(0, 0x0, 0, NULL);
388
389         /* initialize memory allocator */
390         if (alloc_init() == -1) return EFI_LOAD_ERROR;
391
392         status = BS->HandleProtocol(image, &LoadedImageProtocol, (VOID **) &info);
393         if (EFI_ERROR(status)) {
394                 ERR_PRT((L"image handle does not support LOADED_IMAGE protocol"));
395                 return EFI_LOAD_ERROR;
396         }
397
398         VERB_PRT(5,Print(L"Loaded at 0x%lx size=%d bytes code=%d data=%d\n", info->ImageBase, info->ImageSize, info->ImageCodeType, info->ImageDataType));
399
400         /*
401          * verify EDD3.0 status. Users may have to reboot 
402          */
403         edd30_status = check_edd30();
404
405         /*
406          * initialize configuration empire
407          */
408         if (config_init() == -1) goto do_exit;
409
410         /* 
411          * architecture-specific initializations
412          */
413         if (sysdeps_init(info->DeviceHandle) == -1) goto do_exit;
414         if (sysdeps_register_options() == -1) goto do_exit;
415
416         /*
417          * This may be required in case Elilo was booted with absolutely no arguments
418          * Elilo's logic is that just like normal Linux programs at least one argument
419          * (argv[0]) exists at all times and that it usually gives the name of the program
420          * (the command used to start it).
421         ERR_PRT((L"LoadOptions=%x OpenSize=%d", info->LoadOptions, info->LoadOptionsSize));
422          */
423
424         /*
425          * in case there is something wrong with the default boot_device
426          * we default to basic fixups and we need to force interactive
427          * mode to make sure the user has a chance of specifying a kernel
428          */
429         fixupargs(info);
430
431 #if 0
432         Print(L"LoadOptions=%x OpenSize=%d\n", info->LoadOptions, info->LoadOptionsSize);
433         { INTN i; for (i=0; i< info->LoadOptionsSize>>1; i++) Print(L"options[%d]=%d (%c)\n", i, ((CHAR16 *)info->LoadOptions)[i], ((CHAR16 *)info->LoadOptions)[i]); }
434 #endif
435
436         /*
437          * we must copy argument because argify modifies the string.
438          * This caused problems when arguments are coming from NVRAM
439          * as passed by the EFI boot manager
440          *
441          * We add an extra character to the buffer in case the LoadOptions is not 
442          * NULL terminated. The extra space will be used to ADD the extra terminator.
443          */
444         arglist = alloc(info->LoadOptionsSize+sizeof(CHAR16), EfiLoaderData);
445         if (arglist == NULL) {
446                 ERR_PRT((L"cannot copy argument list"));
447                 return EFI_OUT_OF_RESOURCES;
448         }
449         Memcpy(arglist, info->LoadOptions, info->LoadOptionsSize);
450
451         argc = argify(arglist,info->LoadOptionsSize, argv); 
452
453         StrCpy(optstring, ELILO_SHARED_CMDLINE_OPTS);
454         StrCat(optstring, sysdeps_get_cmdline_opts());
455
456         while ((c=Getopt(argc, argv, optstring)) != -1 ) {
457                 switch(c) {
458                         case 'a':
459                                 elilo_opt.alt_check = 1;
460                                 break;
461                         case 'D':
462                                 elilo_opt.debug = 1;
463                                 break;
464                         case 'p':
465                                 elilo_opt.prompt = 1;
466                                 break;
467                         case 'v':
468                                 elilo_opt.verbose++;
469                                 if (elilo_opt.verbose > 5) elilo_opt.verbose = 5;
470                                 break;
471                         case 'h':
472                                 elilo_help();
473                                 ret = EFI_SUCCESS;
474                                 goto do_exit;
475                         case 'd':
476                                 /*
477                                  * zero is a valid value here, so we use the delay-set to mark the
478                                  * fact that the user specified a value on cmdline. See config.c
479                                  */
480                                 elilo_opt.delay = Atoi(Optarg);
481                                 elilo_opt.delay_set = 1;
482                                 break;
483                         case 'E':
484                                 /* don't force EDD30 EFI variable if not already set */
485                                 elilo_opt.edd30_no_force = 1;
486                                 break;
487                         case 'i':
488                                 if (StrLen(Optarg) >= FILENAME_MAXLEN-1) {
489                                         Print(L"initrd filename is limited to %d characters\n", FILENAME_MAXLEN);
490                                         goto do_exit;
491                                 }
492                                 StrCpy(elilo_opt.initrd, Optarg);
493                                 break;
494                         case 'C':
495                                 if (StrLen(Optarg) >= FILENAME_MAXLEN-1) {
496                                         Print(L"config filename is limited to %d characters\n", FILENAME_MAXLEN);
497                                         goto do_exit;
498                                 }
499                                 StrCpy(elilo_opt.config, Optarg);
500                                 break;
501                         case 'M': /* builtin debug tool */
502                                 { mmap_desc_t mdesc; 
503                                         if (get_memmap(&mdesc) == -1) {
504                                                 Print(L"Cannot get memory map\n");
505                                                 return EFI_LOAD_ERROR;
506                                         }
507                                         print_memmap(&mdesc);
508                                         ret = EFI_SUCCESS;
509                                         goto do_exit;
510                                 }
511                         case 'V':
512                                 Print(L"ELILO v%s for EFI/%a\n", ELILO_VERSION, ELILO_ARCH);
513                                 ret = EFI_SUCCESS;
514                                 goto do_exit;
515                         case 'P':
516                                 /* cmdline only option */
517                                 elilo_opt.parse_only =  1;
518                                 break;
519                         case 'c':
520                                 if (StrLen(Optarg) >= FILENAME_MAXLEN-1) {
521                                         Print(L"chooser name is limited to %d characters\n", FILENAME_MAXLEN);
522                                         goto do_exit;
523                                 }
524                                 StrCpy(elilo_opt.chooser, Optarg);
525                                 break;
526                         default:
527                                 /*
528                                  * try system dependent options before declaring error
529                                  */
530                                 if (sysdeps_getopt(c, Optind, Optarg) == 0) continue;
531
532                                 Print(L"Unknown option -%c\n", (CHAR16)c);
533                                 goto do_exit;
534                 }
535         }
536         DBG_PRT((L"Optind=%d optarg=%x argc=%d", Optind, Optarg, argc));
537
538         /*
539          * we can't defer this phase any longer...
540          * Must be done after the elilo_opt are initialized (at least partially)
541          */
542         if (init_devices(info->DeviceHandle) == -1) goto do_exit;
543
544         devices_initialized = TRUE;
545
546         devpath = DevicePathToStr(info->FilePath);
547
548         /*
549          * set per fileops defaults files for configuration and kernel
550          */
551         fops_setdefaults(elilo_opt.default_config, elilo_opt.default_kernel, FILENAME_MAXLEN, devpath);
552
553         /*
554          * XXX: won't be visible if verbose not required from command line
555          */
556         VERB_PRT(2,Print(L"Default config: %s\nDefault_kernel: %s\n",
557                         elilo_opt.default_config,elilo_opt.default_kernel));
558         /*
559          * use default config file if not specified by user
560          */
561         ptr = elilo_opt.config[0] == CHAR_NULL ?  (retry=1,elilo_opt.default_config) : (retry=0,elilo_opt.config);
562
563         /*
564          * parse config file (verbose becomes visible if set)
565          */
566         ret = read_config(ptr, retry);
567         /*
568          * when the config file is not found, we fail only if:
569          *      - the user did not specified interactive mode
570          *      - the user did not explicitely specify the config file
571          */
572         if (ret == EFI_NOT_FOUND || ret == EFI_TFTP_ERROR) {
573                 if (elilo_opt.prompt == 0 && elilo_opt.config[0] != CHAR_NULL) {
574                         Print(L"config file %s not found\n", ptr);
575                         goto do_exit;
576                 }
577                 fops_getdefault_path(dpath, FILENAME_MAXLEN);
578                 if (ret == EFI_TFTP_ERROR)
579                         Print(L"no config file found on TFTP server in %s\n", dpath);
580                 else
581                         Print(L"no config file found in %s\n", dpath);
582         }
583         /*
584          * stop if just doing parsing
585          */
586         if (elilo_opt.parse_only) {
587                 if (ret == EFI_SUCCESS)
588                         Print(L"Config file %s parsed successfully\n", ptr);
589                 goto do_exit;
590         }
591         /*
592          * if there was an error when parsing the config file, then
593          * we force interactive mode to give a chance to the user.
594          * We also clear the error. 
595          */
596         if (ret && argc == 1) {
597                 Print(L"forcing interactive mode because of errors\n");
598                 elilo_opt.prompt = 1;
599         }
600
601         /*
602          * If EDD30 EFI variable was not set to TRUE (or not defined), we
603          * we try to force it. This will take effect at the next reboot.
604          *
605          * Some controllers don't have EDD30 support, in this case forcing it 
606          * may cause problems, therefore we check the edd_no_force option
607          * before making the call.
608          */
609         if (edd30_status == -1 && elilo_opt.edd30_no_force == 0) {
610                 force_edd30();
611         }
612
613         ret = EFI_LOAD_ERROR;
614
615         /*
616          * if the user specified a kernel on the command line
617          * then we don't go to interactive mode even if it
618          * was set in the config file or set because of an
619          * error parsing the config file.
620          */
621         if (argc > Optind) elilo_opt.prompt = 0;
622
623
624         /* set default timeout if going interactive */
625         if ((elilo_opt.prompt && elilo_opt.timeout == 0)) {
626                 elilo_opt.timeout = ELILO_DEFAULT_TIMEOUT;
627         }
628
629         /*
630          * which chooser we will use 
631          */
632         if (init_chooser(info->DeviceHandle) == -1) {
633                 ERR_PRT((L"Cannot find a decent chooser\n"));
634                 goto do_exit;
635         }
636
637         //if (elilo_opt.prompt == 0) VERB_PRT(1, print_devices());
638
639         main_loop(info->DeviceHandle, argv, argc, Optind, image);
640         /* should not return */
641 do_exit:
642         unfixupargs(info);
643
644         //if (arglist) free(arglist);
645
646         /* free all resources assiocated with file accesses */
647         if (devices_initialized) close_devices();
648
649         /* garbage collect all remaining allocations */
650         free_all_memory();
651
652         return ret;
653 }