diff options
| author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2020-10-08 11:53:15 +0000 |
|---|---|---|
| committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2020-10-08 11:53:15 +0000 |
| commit | 3f693b03d640fa3adcd059e44a990b26a1348c03 (patch) | |
| tree | 8bfc944c357d1c9fb3b42a1f8d80b576a551cac0 /usr/src | |
| parent | 18250a42a4b94a65ba1d41b8184d618853b621d1 (diff) | |
| parent | 4d503977b10eb9d89d0aa5114bb17fd9861d2177 (diff) | |
| download | illumos-joyent-3f693b03d640fa3adcd059e44a990b26a1348c03.tar.gz | |
[illumos-gate merge]
commit 4d503977b10eb9d89d0aa5114bb17fd9861d2177
13152 loader: add flat panel info query
commit f3ba4128242a174c2a55b4beaa72d03e0c3b4ccc
13155 loader: cstyle cleanup of pager.c
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/boot/lib/libstand/pager.c | 156 | ||||
| -rw-r--r-- | usr/src/boot/sys/boot/common/gfx_fb.h | 18 | ||||
| -rw-r--r-- | usr/src/boot/sys/boot/i386/libi386/vbe.c | 77 | ||||
| -rw-r--r-- | usr/src/boot/sys/boot/i386/libi386/vbe.h | 34 |
4 files changed, 176 insertions, 109 deletions
diff --git a/usr/src/boot/lib/libstand/pager.c b/usr/src/boot/lib/libstand/pager.c index a916ea3cb6..bbc0c8e0b0 100644 --- a/usr/src/boot/lib/libstand/pager.c +++ b/usr/src/boot/lib/libstand/pager.c @@ -46,18 +46,18 @@ static char *pager_blank = \ void pager_open(void) { - int nlines; - char *cp, *lp; - - nlines = 24; /* sensible default */ - if ((cp = getenv("screen-#rows")) != NULL) { - nlines = strtol(cp, &lp, 0); - } - - p_maxlines = nlines - 1; - if (p_maxlines < 1) - p_maxlines = 1; - p_freelines = p_maxlines; + int nlines; + char *cp, *lp; + + nlines = 24; /* sensible default */ + if ((cp = getenv("screen-#rows")) != NULL) { + nlines = strtol(cp, &lp, 0); + } + + p_maxlines = nlines - 1; + if (p_maxlines < 1) + p_maxlines = 1; + p_freelines = p_maxlines; } /* @@ -66,7 +66,7 @@ pager_open(void) void pager_close(void) { - p_maxlines = -1; + p_maxlines = -1; } /* @@ -82,47 +82,47 @@ pager_close(void) int pager_output(const char *cp) { - int action; - - if (cp == NULL) - return(0); - - for (;;) { - if (*cp == 0) - return(0); - - putchar(*cp); /* always emit character */ - - if (*(cp++) == '\n') { /* got a newline? */ - p_freelines--; - if (p_freelines <= 0) { - printf("%s", pager_prompt1); - action = 0; - while (action == 0) { - switch(getchar()) { - case '\r': - case '\n': - p_freelines = 1; - action = 1; - break; - case ' ': - p_freelines = p_maxlines; - action = 1; - break; - case 'q': - case 'Q': - action = 2; - break; - default: - break; - } + int action; + + if (cp == NULL) + return (0); + + for (;;) { + if (*cp == 0) + return (0); + + putchar(*cp); /* always emit character */ + + if (*(cp++) == '\n') { /* got a newline? */ + p_freelines--; + if (p_freelines <= 0) { + printf("%s", pager_prompt1); + action = 0; + while (action == 0) { + switch (getchar()) { + case '\r': + case '\n': + p_freelines = 1; + action = 1; + break; + case ' ': + p_freelines = p_maxlines; + action = 1; + break; + case 'q': + case 'Q': + action = 2; + break; + default: + break; + } + } + printf("\r%s\r", pager_blank); + if (action == 2) + return (1); + } } - printf("\r%s\r", pager_blank); - if (action == 2) - return(1); - } } - } } /* @@ -131,32 +131,32 @@ pager_output(const char *cp) int pager_file(const char *fname) { - char buf[80]; - size_t hmuch; - int fd; - int result; - - if ((fd = open(fname, O_RDONLY)) == -1) { - printf("can't open '%s': %s\n", fname, strerror(errno)); - return(-1); - } - - for (;;) { - hmuch = read(fd, buf, sizeof(buf) - 1); - if (hmuch == -1) { - result = -1; - break; - } - if (hmuch == 0) { - result = 0; - break; + char buf[80]; + size_t hmuch; + int fd; + int result; + + if ((fd = open(fname, O_RDONLY)) == -1) { + printf("can't open '%s': %s\n", fname, strerror(errno)); + return (-1); } - buf[hmuch] = 0; - if (pager_output(buf)) { - result = 1; - break; + + for (;;) { + hmuch = read(fd, buf, sizeof (buf) - 1); + if (hmuch == -1) { + result = -1; + break; + } + if (hmuch == 0) { + result = 0; + break; + } + buf[hmuch] = 0; + if (pager_output(buf)) { + result = 1; + break; + } } - } - close(fd); - return(result); + close(fd); + return (result); } diff --git a/usr/src/boot/sys/boot/common/gfx_fb.h b/usr/src/boot/sys/boot/common/gfx_fb.h index de199d1472..cb2d37042d 100644 --- a/usr/src/boot/sys/boot/common/gfx_fb.h +++ b/usr/src/boot/sys/boot/common/gfx_fb.h @@ -93,15 +93,21 @@ struct vesa_edid_info { uint8_t checksum; } __packed; +/* + * Number of pixels and lines is 12-bit int, valid values 0-4095. + */ +#define EDID_MAX_PIXELS 4095 +#define EDID_MAX_LINES 4095 + #define GET_EDID_INFO_WIDTH(edid_info, timings_num) \ - ((edid_info)->detailed_timings[(timings_num)].horizontal_active_lo | \ - (((uint_t)(edid_info)->detailed_timings[(timings_num)].horizontal_hi & \ - 0xf0) << 4)) + ((edid_info)->detailed_timings[(timings_num)].horizontal_active_lo | \ + (((uint_t)(edid_info)->detailed_timings[(timings_num)].horizontal_hi & \ + 0xf0) << 4)) #define GET_EDID_INFO_HEIGHT(edid_info, timings_num) \ - ((edid_info)->detailed_timings[(timings_num)].vertical_active_lo | \ - (((uint_t)(edid_info)->detailed_timings[(timings_num)].vertical_hi & \ - 0xf0) << 4)) + ((edid_info)->detailed_timings[(timings_num)].vertical_active_lo | \ + (((uint_t)(edid_info)->detailed_timings[(timings_num)].vertical_hi & \ + 0xf0) << 4)) extern multiboot_tag_framebuffer_t gfx_fb; diff --git a/usr/src/boot/sys/boot/i386/libi386/vbe.c b/usr/src/boot/sys/boot/i386/libi386/vbe.c index d8ad4ed643..c3cc09dd53 100644 --- a/usr/src/boot/sys/boot/i386/libi386/vbe.c +++ b/usr/src/boot/sys/boot/i386/libi386/vbe.c @@ -180,6 +180,20 @@ biosvbe_ddc_caps(void) return (v86.ebx & 0xffff); } +/* Function 11h BL=01h - Flat Panel status */ +static int +biosvbe_ddc_read_flat_panel_info(void *buf) +{ + v86.ctl = V86_FLAGS; + v86.addr = 0x10; + v86.eax = 0x4f11; /* Flat Panel Interface extensions */ + v86.ebx = 1; /* Return Flat Panel Information */ + v86.es = VTOPSEG(buf); + v86.edi = VTOPOFF(buf); + v86int(); + return (v86.eax & 0xffff); +} + /* Function 15h BL=01h - Read EDID */ static int biosvbe_ddc_read_edid(int blockno, void *buf) @@ -495,6 +509,7 @@ vbe_get_edid(uint_t *pwidth, uint_t *pheight) edid_info = bio_alloc(sizeof (*edid_info)); if (edid_info == NULL) return (ret); + memset(edid_info, 0, sizeof (*edid_info)); if (VBE_ERROR(biosvbe_ddc_read_edid(0, edid_info))) goto done; @@ -511,12 +526,37 @@ vbe_get_edid(uint_t *pwidth, uint_t *pheight) *pwidth = GET_EDID_INFO_WIDTH(edid_info, 0); *pheight = GET_EDID_INFO_HEIGHT(edid_info, 0); - ret = true; + if (*pwidth > 0 && *pwidth <= EDID_MAX_PIXELS && + *pheight > 0 && *pheight <= EDID_MAX_LINES) + ret = true; done: bio_free(edid_info, sizeof (*edid_info)); return (ret); } +static bool +vbe_get_flatpanel(uint_t *pwidth, uint_t *pheight) +{ + struct flatpanelinfo *fp_info; + bool ret = false; + + fp_info = bio_alloc(sizeof (*fp_info)); + if (fp_info == NULL) + return (ret); + memset(fp_info, 0, sizeof (*fp_info)); + + if (VBE_ERROR(biosvbe_ddc_read_flat_panel_info(fp_info))) + goto done; + + *pwidth = fp_info->HorizontalSize; + *pheight = fp_info->VerticalSize; + ret = true; + +done: + bio_free(fp_info, sizeof (*fp_info)); + return (ret); +} + static void vbe_print_vbe_info(struct vbeinfoblock *vbep) { @@ -554,7 +594,8 @@ vbe_modelist(int depth) uint16_t mode; int nmodes = 0, safety = 0; int ddc_caps; - uint_t edid_width, edid_height; + uint_t width, height; + bool edid = false; if (!vbe_check()) return; @@ -567,11 +608,15 @@ vbe_modelist(int depth) if (ddc_caps & 2) printf(" [DDC2]"); - if (vbe_get_edid(&edid_width, &edid_height)) - printf(": EDID %dx%d\n", edid_width, edid_height); + edid = vbe_get_edid(&width, &height); + if (edid) + printf(": EDID %dx%d\n", width, height); else printf(": no EDID information\n"); } + if (!edid) + if (vbe_get_flatpanel(&width, &height)) + printf(": Panel %dx%d\n", width, height); memset(vbe, 0, sizeof (vbe)); memcpy(vbe->VbeSignature, "VBE2", 4); @@ -691,19 +736,29 @@ vbe_print_mode(void) } } +/* + * Try EDID preferred mode, if EDID or the suggested mode is not available, + * then try flat panel information. + * Fall back to VBE_DEFAULT_MODE. + */ int vbe_default_mode(void) { int modenum; - uint_t edid_width, edid_height; + uint_t width, height; - if (vbe_get_edid(&edid_width, &edid_height)) { - modenum = vbe_find_mode_xydm(edid_width, edid_height, -1, -1); - if (modenum == 0) - modenum = vbe_find_mode(VBE_DEFAULT_MODE); - } else { - modenum = vbe_find_mode(VBE_DEFAULT_MODE); + modenum = 0; + if (vbe_get_edid(&width, &height)) + modenum = vbe_find_mode_xydm(width, height, -1, -1); + + if (modenum == 0 && + vbe_get_flatpanel(&width, &height)) { + modenum = vbe_find_mode_xydm(width, height, -1, -1); } + + /* Still no mode? Fall back to default. */ + if (modenum == 0) + modenum = vbe_find_mode(VBE_DEFAULT_MODE); return (modenum); } diff --git a/usr/src/boot/sys/boot/i386/libi386/vbe.h b/usr/src/boot/sys/boot/i386/libi386/vbe.h index 7b428b968d..dc732a05bc 100644 --- a/usr/src/boot/sys/boot/i386/libi386/vbe.h +++ b/usr/src/boot/sys/boot/i386/libi386/vbe.h @@ -33,7 +33,10 @@ * VESA disabled. */ -#define VBE_DEFAULT_MODE "800x600" +#ifndef _VBE_H +#define _VBE_H + +#define VBE_DEFAULT_MODE "800x600" struct vbeinfoblock { char VbeSignature[4]; @@ -61,8 +64,10 @@ struct modeinfoblock { uint8_t XCharSize, YCharSize, NumberOfPlanes, BitsPerPixel; uint8_t NumberOfBanks, MemoryModel, BankSize, NumberOfImagePages; uint8_t Reserved1; - /* Direct Color fields - (required for direct/6 and YUV/7 memory models) */ + /* + * Direct Color fields + * (required for direct/6 and YUV/7 memory models) + */ uint8_t RedMaskSize, RedFieldPosition; uint8_t GreenMaskSize, GreenFieldPosition; uint8_t BlueMaskSize, BlueFieldPosition; @@ -108,17 +113,16 @@ struct paletteentry { struct flatpanelinfo { - uint16_t HorizontalSize; - uint16_t VerticalSize; - uint16_t PanelType; - uint8_t RedBPP; - uint8_t GreenBPP; - uint8_t BlueBPP; - uint8_t ReservedBPP; - uint32_t ReservedOffScreenMemSize; - uint32_t ReservedOffScreenMemPtr; - - uint8_t Reserved[14]; + uint16_t HorizontalSize; /* Horizontal Size in Pixels */ + uint16_t VerticalSize; /* Vertical Size in Lines */ + uint16_t PanelType; /* Flat Panel Type */ + uint8_t RedBPP; /* Red Bits Per Primary */ + uint8_t GreenBPP; /* Green Bits Per Primary */ + uint8_t BlueBPP; /* Blue Bits Per Primary */ + uint8_t ReservedBPP; /* Reserved Bits Per Primary */ + uint32_t RsvdOffScreenMemSize; /* Size in KB of Offscreen Memory */ + uint32_t RsvdOffScreenMemPtr; /* Pointer to reserved offscreen memory */ + uint8_t Reserved[14]; /* remainder of FPInfo */ } __packed; #define VBE_BASE_MODE (0x100) /* VBE 3.0 page 18 */ @@ -143,3 +147,5 @@ int vbe_set_mode(int); int vbe_get_mode(void); int vbe_set_palette(const struct paletteentry *, size_t); void vbe_modelist(int); + +#endif /* _VBE_H */ |
