On Fri, Oct 06, 2017 at 05:15:20AM +0000, YASUOKA Masahiko wrote:
> On Tue, 3 Oct 2017 18:15:33 -0500
> Andrew Daugherity <[email protected]> wrote:
> > I tested this diff in combination with your "Implement machine gop command"
> > diff on a Dell PowerEdge R230 and a VirtualBox VM (EFI enabled).  No
> > regressions, however 'machine gop' doesn't work quite how I expected it to
> > -- it seems the video mode set with it only applies to the bootloader, and
> > once the kernel loads, it sets a different mode (possibly a bad one).  I
> > was hoping the kernel would use the mode I just set.
> 
> I also expected that the kernel uses the mode to which the gop command
> set.  I think it's more useful.
> 
> The diff is updated.
>
> comments?
See my updated diff for reusing the gopi struct, please.

Searching for and setting a better mode only if the user didn't pick one
manually before is definitely a good idea, thanks.

Udated diff implementing `machine gop [n]' attached.

> Index: sys/arch/amd64/stand/efiboot/efiboot.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/efiboot.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 efiboot.c
> --- sys/arch/amd64/stand/efiboot/efiboot.c    6 Oct 2017 04:52:22 -0000       
> 1.24
> +++ sys/arch/amd64/stand/efiboot/efiboot.c    6 Oct 2017 05:09:29 -0000
> @@ -51,6 +51,7 @@ static EFI_GUID              imgp_guid = LOADED_IMA
>  static EFI_GUID               blkio_guid = BLOCK_IO_PROTOCOL;
>  static EFI_GUID               devp_guid = DEVICE_PATH_PROTOCOL;
>  u_long                        efi_loadaddr;
> +static int            efi_gopmode = -1;
>  
>  static int    efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
>  static int    efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *,
> @@ -722,7 +723,7 @@ efi_makebootargs(void)
>       EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
>                               *gopi;
>       bios_efiinfo_t           ei;
> -     int                      curmode, bestmode = -1;
> +     int                      curmode;
>       UINTN                    sz, gopsiz, bestsiz = 0;
>       EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
>                               *info;
> @@ -748,20 +749,23 @@ efi_makebootargs(void)
>       status = EFI_CALL(BS->LocateProtocol, &gop_guid, NULL,
>           (void **)&gop);
>       if (!EFI_ERROR(status)) {
> -             for (i = 0; i < gop->Mode->MaxMode; i++) {
> -                     status = EFI_CALL(gop->QueryMode, gop, i, &sz, &info);
> -                     if (EFI_ERROR(status))
> -                             continue;
> -                     gopsiz = info->HorizontalResolution *
> -                         info->VerticalResolution;
> -                     if (gopsiz > bestsiz) {
> -                             bestmode = i;
> -                             bestsiz = gopsiz;
> +             if (efi_gopmode < 0) {
> +                     for (i = 0; i < gop->Mode->MaxMode; i++) {
> +                             status = EFI_CALL(gop->QueryMode, gop, i, &sz,
> +                                 &info);
> +                             if (EFI_ERROR(status))
> +                                     continue;
> +                             gopsiz = info->HorizontalResolution *
> +                                 info->VerticalResolution;
> +                             if (gopsiz > bestsiz) {
> +                                     efi_gopmode = i;
> +                                     bestsiz = gopsiz;
> +                             }
>                       }
>               }
> -             if (bestmode >= 0) {
> +             if (efi_gopmode >= 0 && efi_gopmode != gop->Mode->Mode) {
>                       curmode = gop->Mode->Mode;
> -                     if (efi_gop_setmode(gop, bestmode) != EFI_SUCCESS)
> +                     if (efi_gop_setmode(gop, efi_gopmode) != EFI_SUCCESS)
>                               (void)efi_gop_setmode(gop, curmode);
>               }
>  
> @@ -882,5 +886,49 @@ int
>  Xpoweroff_efi(void)
>  {
>       EFI_CALL(RS->ResetSystem, EfiResetShutdown, EFI_SUCCESS, 0, NULL);
> +     return (0);
> +}
> +
> +int
> +Xgop_efi(void)
> +{
> +     EFI_STATUS               status;
> +     EFI_GRAPHICS_OUTPUT     *gop;
> +     EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
> +                             *info;
> +     int                      i, mode = -1;
> +     UINTN                    sz;
> +
> +     status = EFI_CALL(BS->LocateProtocol, &gop_guid, NULL,
> +         (void **)&gop);
> +     if (EFI_ERROR(status))
> +             return (0);
> +
> +     if (cmd.argc >= 2) {
> +             mode = strtol(cmd.argv[1], NULL, 10);
> +             if (0 <= mode && mode < gop->Mode->MaxMode) {
> +                     status = EFI_CALL(gop->QueryMode, gop, mode,
> +                         &sz, &info);
> +                     if (!EFI_ERROR(status)) {
> +                             if (efi_gop_setmode(gop, mode)
> +                                 == EFI_SUCCESS)
> +                                     efi_gopmode = mode;
> +                     }
> +             }
> +     } else {
> +             for (i = 0; i < gop->Mode->MaxMode; i++) {
> +                     status = EFI_CALL(gop->QueryMode, gop, i, &sz,
> +                         &info);
> +                     if (EFI_ERROR(status))
> +                             continue;
> +                     printf("Mode %d: %d x %d (stride = %d)\n", i,
> +                         info->HorizontalResolution,
> +                         info->VerticalResolution,
> +                         info->PixelsPerScanLine);
> +             }
> +             printf("\n");
> +     }
> +     printf("Current Mode = %d\n", gop->Mode->Mode);
> +
>       return (0);
>  }
> Index: sys/arch/amd64/stand/efiboot/efiboot.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/efiboot.h,v
> retrieving revision 1.2
> diff -u -p -r1.2 efiboot.h
> --- sys/arch/amd64/stand/efiboot/efiboot.h    31 May 2017 08:40:32 -0000      
> 1.2
> +++ sys/arch/amd64/stand/efiboot/efiboot.h    6 Oct 2017 05:09:29 -0000
> @@ -30,6 +30,7 @@ void         efi_com_init(struct consdev *);
>  int   efi_com_getc(dev_t);
>  void  efi_com_putc(dev_t, int);
>  int   Xvideo_efi(void);
> +int   Xgop_efi(void);
>  int   Xexit_efi(void);
>  void  efi_makebootargs(void);
>  
> Index: sys/arch/amd64/stand/libsa/cmd_i386.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/stand/libsa/cmd_i386.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 cmd_i386.c
> --- sys/arch/amd64/stand/libsa/cmd_i386.c     31 May 2017 08:23:33 -0000      
> 1.11
> +++ sys/arch/amd64/stand/libsa/cmd_i386.c     6 Oct 2017 05:09:29 -0000
> @@ -62,6 +62,7 @@ const struct cmd_table cmd_machine[] = {
>       { "memory",     CMDT_CMD, Xmemory },
>  #ifdef EFIBOOT
>       { "video",      CMDT_CMD, Xvideo_efi },
> +     { "gop",        CMDT_CMD, Xgop_efi },
>       { "exit",       CMDT_CMD, Xexit_efi },
>       { "poweroff",   CMDT_CMD, Xpoweroff_efi },
>  #endif
> 
> 


Implement `machine gop [n]' completely analogue to `machine video [n]'
in the bootloader so users can list and set available frame buffer modes.
---
 sys/arch/amd64/stand/efiboot/efiboot.c | 68 ++++++++++++++++++++++++++++------
 sys/arch/amd64/stand/efiboot/efiboot.h |  1 +
 sys/arch/amd64/stand/libsa/cmd_i386.c  |  1 +
 3 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/sys/arch/amd64/stand/efiboot/efiboot.c 
b/sys/arch/amd64/stand/efiboot/efiboot.c
index 283f9ab356e..cc04b07dd52 100644
--- a/sys/arch/amd64/stand/efiboot/efiboot.c
+++ b/sys/arch/amd64/stand/efiboot/efiboot.c
@@ -708,6 +708,7 @@ static EFI_GUID                      smbios_guid = 
SMBIOS_TABLE_GUID;
 static EFI_GRAPHICS_OUTPUT     *gop;
 static EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
                                *gopi;
+static int                      efi_gopmode = -1;
 
 #define        efi_guidcmp(_a, _b)     memcmp((_a), (_b), sizeof(EFI_GUID))
 
@@ -729,7 +730,7 @@ efi_makebootargs(void)
        int                      i;
        EFI_STATUS               status;
        bios_efiinfo_t           ei;
-       int                      curmode, bestmode = -1;
+       int                      curmode;
        UINTN                    sz, gopsiz, bestsiz = 0;
 
        memset(&ei, 0, sizeof(ei));
@@ -753,20 +754,23 @@ efi_makebootargs(void)
        status = EFI_CALL(BS->LocateProtocol, &gop_guid, NULL,
            (void **)&gop);
        if (!EFI_ERROR(status)) {
-               for (i = 0; i < gop->Mode->MaxMode; i++) {
-                       status = EFI_CALL(gop->QueryMode, gop, i, &sz, &gopi);
-                       if (EFI_ERROR(status))
-                               continue;
-                       gopsiz = gopi->HorizontalResolution *
-                           gopi->VerticalResolution;
-                       if (gopsiz > bestsiz) {
-                               bestmode = i;
-                               bestsiz = gopsiz;
+               if (efi_gopmode < 0) {
+                       for (i = 0; i < gop->Mode->MaxMode; i++) {
+                               status = EFI_CALL(gop->QueryMode, gop,
+                                   i, &sz, &gopi);
+                               if (EFI_ERROR(status))
+                                       continue;
+                               gopsiz = gopi->HorizontalResolution *
+                                   gopi->VerticalResolution;
+                               if (gopsiz > bestsiz) {
+                                       efi_gopmode = i;
+                                       bestsiz = gopsiz;
+                               }
                        }
                }
-               if (bestmode >= 0) {
+               if (efi_gopmode >= 0 && efi_gopmode != gop->Mode->Mode) {
                        curmode = gop->Mode->Mode;
-                       if (efi_gop_setmode(bestmode) != EFI_SUCCESS)
+                       if (efi_gop_setmode(efi_gopmode) != EFI_SUCCESS)
                                (void)efi_gop_setmode(curmode);
                }
 
@@ -892,3 +896,43 @@ Xpoweroff_efi(void)
        EFI_CALL(RS->ResetSystem, EfiResetShutdown, EFI_SUCCESS, 0, NULL);
        return (0);
 }
+
+int
+Xgop_efi(void)
+{
+       EFI_STATUS      status;
+       int             i, mode = -1;
+       UINTN           sz;
+
+       status = EFI_CALL(BS->LocateProtocol, &gop_guid, NULL,
+           (void **)&gop);
+       if (EFI_ERROR(status))
+               return (0);
+
+       if (cmd.argc >= 2) {
+               mode = strtol(cmd.argv[1], NULL, 10);
+               if (0 <= mode && mode < gop->Mode->MaxMode) {
+                       status = EFI_CALL(gop->QueryMode, gop, mode,
+                           &sz, &gopi);
+                       if (!EFI_ERROR(status)) {
+                               if (efi_gop_setmode(mode) == EFI_SUCCESS)
+                                       efi_gopmode = mode;
+                       }
+               }
+       } else {
+               for (i = 0; i < gop->Mode->MaxMode; i++) {
+                       status = EFI_CALL(gop->QueryMode, gop, i, &sz,
+                           &gopi);
+                       if (EFI_ERROR(status))
+                               continue;
+                       printf("Mode %d: %d x %d (stride = %d)\n", i,
+                           gopi->HorizontalResolution,
+                           gopi->VerticalResolution,
+                           gopi->PixelsPerScanLine);
+               }
+               printf("\n");
+       }
+       printf("Current Mode = %d\n", gop->Mode->Mode);
+
+       return (0);
+}
diff --git a/sys/arch/amd64/stand/efiboot/efiboot.h 
b/sys/arch/amd64/stand/efiboot/efiboot.h
index 8a07d5b46b3..3f5f5b3352c 100644
--- a/sys/arch/amd64/stand/efiboot/efiboot.h
+++ b/sys/arch/amd64/stand/efiboot/efiboot.h
@@ -30,6 +30,7 @@ void   efi_com_init(struct consdev *);
 int     efi_com_getc(dev_t);
 void    efi_com_putc(dev_t, int);
 int     Xvideo_efi(void);
+int     Xgop_efi(void);
 int     Xexit_efi(void);
 void    efi_makebootargs(void);
 
diff --git a/sys/arch/amd64/stand/libsa/cmd_i386.c 
b/sys/arch/amd64/stand/libsa/cmd_i386.c
index 592cca49547..ee3b7f3cd63 100644
--- a/sys/arch/amd64/stand/libsa/cmd_i386.c
+++ b/sys/arch/amd64/stand/libsa/cmd_i386.c
@@ -62,6 +62,7 @@ const struct cmd_table cmd_machine[] = {
        { "memory",     CMDT_CMD, Xmemory },
 #ifdef EFIBOOT
        { "video",      CMDT_CMD, Xvideo_efi },
+       { "gop",        CMDT_CMD, Xgop_efi },
        { "exit",       CMDT_CMD, Xexit_efi },
        { "poweroff",   CMDT_CMD, Xpoweroff_efi },
 #endif
-- 
2.14.2


Reply via email to