summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2020-10-08 11:53:15 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2020-10-08 11:53:15 +0000
commit3f693b03d640fa3adcd059e44a990b26a1348c03 (patch)
tree8bfc944c357d1c9fb3b42a1f8d80b576a551cac0 /usr/src
parent18250a42a4b94a65ba1d41b8184d618853b621d1 (diff)
parent4d503977b10eb9d89d0aa5114bb17fd9861d2177 (diff)
downloadillumos-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.c156
-rw-r--r--usr/src/boot/sys/boot/common/gfx_fb.h18
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/vbe.c77
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/vbe.h34
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 */