Eliminate operatingDevices member and PIPE_* values.

operatingDevices and MonType1/MonType2 duplicate information already stored
in the device structures. Eliminate them and replace uses with direct
references to the appropriate other data.
(cherry picked from 3ab7f96932 commit)
This commit is contained in:
Keith Packard 2006-11-04 00:46:18 -08:00 committed by Eric Anholt
parent 0b2d36d4f0
commit f1ff01e31e
6 changed files with 99 additions and 221 deletions

View File

@ -86,26 +86,6 @@ typedef struct _I830OutputRec I830OutputRec, *I830OutputPtr;
* Paulo César Pereira de Andrade <pcpa@conectiva.com.br>.
*/
#define PIPE_CRT_ID 0
#define PIPE_TV_ID 1
#define PIPE_DFP_ID 2
#define PIPE_LFP_ID 3
#define PIPE_CRT2_ID 4
#define PIPE_TV2_ID 5
#define PIPE_DFP2_ID 6
#define PIPE_LFP2_ID 7
#define PIPE_NUM_ID 8
#define PIPE_NONE 0<<0
#define PIPE_CRT 1<<0
#define PIPE_TV 1<<1
#define PIPE_DFP 1<<2
#define PIPE_LFP 1<<3
#define PIPE_CRT2 1<<4
#define PIPE_TV2 1<<5
#define PIPE_DFP2 1<<6
#define PIPE_LFP2 1<<7
typedef struct _I830Rec *I830Ptr;
typedef void (*I830WriteIndexedByteFunc)(I830Ptr pI830, IOADDRESS addr,
@ -319,7 +299,9 @@ typedef struct _I830Rec {
int CloneVDisplay;
I830EntPtr entityPrivate;
#if 0
int pipe, origPipe;
#endif
int init;
unsigned int bufferOffset; /* for I830SelectBuffer */
@ -396,9 +378,6 @@ typedef struct _I830Rec {
Bool CursorIsARGB;
CursorPtr pCurs;
int MonType1;
int MonType2;
DGAModePtr DGAModes;
int numDGAModes;
Bool DGAactive;
@ -474,7 +453,6 @@ typedef struct _I830Rec {
CARD32 saveSWF4;
Bool checkDevices;
int operatingDevices;
/* [0] is Pipe A, [1] is Pipe B. */
int availablePipes;
@ -668,6 +646,10 @@ extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem);
extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
char *name);
/* i830_display.c */
Bool
i830PipeHasType (ScrnInfoPtr pScrn, int pipe, int type);
/* i830_crt.c */
void i830_crt_init(ScrnInfoPtr pScrn);

View File

@ -170,7 +170,7 @@ static Bool
i830_crt_detect_load(ScrnInfoPtr pScrn, I830OutputPtr output)
{
I830Ptr pI830 = I830PTR(pScrn);
CARD32 adpa, pipeconf;
CARD32 adpa, pipeconf, bclrpat;
CARD8 st00;
int pipeconf_reg, bclrpat_reg, dpll_reg;
int pipe;
@ -198,9 +198,10 @@ i830_crt_detect_load(ScrnInfoPtr pScrn, I830OutputPtr output)
((pipe == 1) ? ADPA_PIPE_B_SELECT : 0));
}
/* Set the border color to red, green. Maybe we should save/restore this
/* Set the border color to purple. Maybe we should save/restore this
* reg.
*/
bclrpat = INREG(bclrpat_reg);
OUTREG(bclrpat_reg, 0x00500050);
/* Force the border color through the active region */
@ -211,6 +212,7 @@ i830_crt_detect_load(ScrnInfoPtr pScrn, I830OutputPtr output)
st00 = pI830->readStandard(pI830, 0x3c2);
/* Restore previous settings */
OUTREG(bclrpat_reg, bclrpat);
OUTREG(pipeconf_reg, pipeconf);
OUTREG(ADPA, adpa);

View File

@ -60,6 +60,24 @@ i830PrintPll(char *prefix, int refclk, int m1, int m2, int n, int p1, int p2)
m1, m2, n, p1, p2);
}
/**
* Returns whether any output on the specified pipe is an LVDS output
*/
Bool
i830PipeHasType (ScrnInfoPtr pScrn, int pipe, int type)
{
I830Ptr pI830 = I830PTR(pScrn);
int i;
for (i = 0; i < pI830->num_outputs; i++)
if (!pI830->output[i].disabled && pI830->output[i].pipe == pipe)
{
if (pI830->output[i].type == type)
return TRUE;
}
return FALSE;
}
/**
* Returns whether the given set of divisors are valid for a given refclk with
* the given outputs.
@ -68,7 +86,7 @@ i830PrintPll(char *prefix, int refclk, int m1, int m2, int n, int p1, int p2)
* clk = refclk * (5 * m1 + m2) / n / (p1 * p2)
*/
static Bool
i830PllIsValid(ScrnInfoPtr pScrn, int outputs, int refclk, int m1, int m2,
i830PllIsValid(ScrnInfoPtr pScrn, int pipe, int refclk, int m1, int m2,
int n, int p1, int p2)
{
I830Ptr pI830 = I830PTR(pScrn);
@ -87,7 +105,7 @@ i830PllIsValid(ScrnInfoPtr pScrn, int outputs, int refclk, int m1, int m2,
max_n = 8;
min_p1 = 1;
max_p1 = 8;
if (outputs & PIPE_LCD_ACTIVE) {
if (i830PipeHasType (pScrn, pipe, I830_OUTPUT_LVDS)) {
min_p = 7;
max_p = 98;
} else {
@ -153,7 +171,7 @@ i830PllIsValid(ScrnInfoPtr pScrn, int outputs, int refclk, int m1, int m2,
* clk = refclk * (5 * m1 + m2) / n / (p1 * p2)
*/
static Bool
i830FindBestPLL(ScrnInfoPtr pScrn, int outputs, int target, int refclk,
i830FindBestPLL(ScrnInfoPtr pScrn, int pipe, int target, int refclk,
int *outm1, int *outm2, int *outn, int *outp1, int *outp2)
{
I830Ptr pI830 = I830PTR(pScrn);
@ -170,7 +188,7 @@ i830FindBestPLL(ScrnInfoPtr pScrn, int outputs, int target, int refclk,
max_n = 8;
min_p1 = 1;
max_p1 = 8;
if (outputs & PIPE_LCD_ACTIVE) {
if (i830PipeHasType (pScrn, pipe, I830_OUTPUT_LVDS)) {
if (target < 200000) /* XXX: Is this the right cutoff? */
p2 = 14;
else
@ -203,7 +221,7 @@ i830FindBestPLL(ScrnInfoPtr pScrn, int outputs, int target, int refclk,
for (p1 = min_p1; p1 <= max_p1; p1++) {
int clock, this_err;
if (!i830PllIsValid(pScrn, outputs, refclk, m1, m2, n,
if (!i830PllIsValid(pScrn, pipe, refclk, m1, m2, n,
p1, p2)) {
continue;
}
@ -377,7 +395,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
Bool ok, is_sdvo = FALSE, is_dvo = FALSE;
Bool is_crt = FALSE, is_lvds = FALSE, is_tv = FALSE;
int refclk, pixel_clock;
int outputs, i;
int i;
int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
int fp_reg = (pipe == 0) ? FPA0 : FPB0;
@ -393,11 +411,6 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
if (pipe == 0)
outputs = pI830->operatingDevices & 0xff;
else
outputs = (pI830->operatingDevices >> 8) & 0xff;
if (I830ModesEqual(&pI830Pipe->curMode, pMode))
return TRUE;
@ -502,7 +515,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
} else {
refclk = 48000;
}
ok = i830FindBestPLL(pScrn, outputs, pixel_clock, refclk, &m1, &m2, &n,
ok = i830FindBestPLL(pScrn, pipe, pixel_clock, refclk, &m1, &m2, &n,
&p1, &p2);
if (!ok) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@ -706,6 +719,22 @@ i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
}
}
/**
* Return whether any outputs are connected to the specified pipe
*/
static Bool
i830PipeInUse (ScrnInfoPtr pScrn, int pipe)
{
I830Ptr pI830 = I830PTR(pScrn);
int i;
for (i = 0; i < pI830->num_outputs; i++)
if (!pI830->output[i].disabled && pI830->output[i].pipe == pipe)
return TRUE;
return FALSE;
}
/**
* This function configures the screens in clone mode on
* all active outputs using a mode similar to the specified mode.
@ -726,8 +755,8 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
didLock = I830DRILock(pScrn);
#endif
pI830->pipes[0].planeEnabled = (pI830->operatingDevices & 0xff) != 0;
pI830->pipes[1].planeEnabled = (pI830->operatingDevices & 0xff00) != 0;
for (i = 0; i < pI830->availablePipes; i++)
pI830->pipes[i].planeEnabled = i830PipeInUse (pScrn, i);
for (i = 0; i < pI830->num_outputs; i++)
pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);

View File

@ -387,88 +387,6 @@ I830ProbeDDC(ScrnInfoPtr pScrn, int index)
ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
}
/*
* Returns a string matching the device corresponding to the first bit set
* in "device". savedDevice is then set to device with that bit cleared.
* Subsequent calls with device == -1 will use savedDevice.
*/
static const char *displayDevices[] = {
"CRT",
"TV",
"DFP (digital flat panel)",
"LFP (local flat panel)",
"CRT2 (second CRT)",
"TV2 (second TV)",
"DFP2 (second digital flat panel)",
"LFP2 (second local flat panel)",
NULL
};
static const char *
DeviceToString(int device)
{
static int savedDevice = -1;
int bit = 0;
const char *name;
if (device == -1) {
device = savedDevice;
bit = 0;
}
if (device == -1)
return NULL;
while (displayDevices[bit]) {
if (device & (1 << bit)) {
name = displayDevices[bit];
savedDevice = device & ~(1 << bit);
bit++;
return name;
}
bit++;
}
return NULL;
}
static void
PrintDisplayDeviceInfo(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
int pipe, n;
int displays;
DPRINTF(PFX, "PrintDisplayDeviceInfo\n");
displays = pI830->operatingDevices;
if (displays == -1) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"No active display devices.\n");
return;
}
/* Check for active devices connected to each display pipe. */
for (n = 0; n < pI830->availablePipes; n++) {
pipe = ((displays >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK);
if (pipe) {
const char *name;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Currently active displays on Pipe %c:\n", PIPE_NAME(n));
name = DeviceToString(pipe);
do {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t%s\n", name);
name = DeviceToString(-1);
} while (name);
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"No active displays on Pipe %c.\n", PIPE_NAME(n));
}
}
}
static int
I830DetectMemory(ScrnInfoPtr pScrn)
{
@ -1268,9 +1186,10 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
I830PreInitDDC(pScrn);
pI830->MonType1 = PIPE_NONE;
pI830->MonType2 = PIPE_NONE;
#if 0
/*
* This moves to generic RandR-based configuration code
*/
if ((s = xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT)) &&
I830IsPrimary(pScrn)) {
char *Mon1;
@ -1355,7 +1274,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
else
pI830->pipe = 1;
pI830->operatingDevices = (pI830->MonType2 << 8) | pI830->MonType1;
} else if (I830IsPrimary(pScrn)) {
/* Choose a default set of outputs to use based on what we've detected.
*
@ -1401,7 +1319,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->pipe = 0;
else
pI830->pipe = 1;
pI830->operatingDevices = (pI830->MonType2 << 8) | pI830->MonType1;
if (pI830->MonType1 != 0 && pI830->MonType2 != 0) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@ -1410,11 +1327,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
} else {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
pI830->operatingDevices = pI8301->operatingDevices;
pI830->pipe = !pI8301->pipe;
pI830->MonType1 = pI8301->MonType1;
pI830->MonType2 = pI8301->MonType2;
}
#endif
if (xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
if (pI830->availablePipes == 1) {
@ -1434,38 +1351,23 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
/* Perform the pipe assignment of outputs. This code shouldn't exist,
* but for now we're supporting the existing MonitorLayout configuration
* scheme.
/* Perform the pipe assignment of outputs. This is a kludge until
* we have better configuration support in the generic RandR code
*/
for (i = 0; i < pI830->num_outputs; i++) {
pI830->output[i].disabled = FALSE;
switch (pI830->output[i].type) {
case I830_OUTPUT_LVDS:
if (pI830->MonType1 & PIPE_LFP)
pI830->output[i].pipe = 0;
else if (pI830->MonType2 & PIPE_LFP)
pI830->output[i].pipe = 1;
else
pI830->output[i].disabled = TRUE;
/* LVDS must live on pipe B for two-pipe devices */
pI830->output[i].pipe = pI830->availablePipes - 1;
break;
case I830_OUTPUT_ANALOG:
if (pI830->MonType1 & PIPE_CRT)
pI830->output[i].pipe = 0;
else if (pI830->MonType2 & PIPE_CRT)
pI830->output[i].pipe = 1;
else
pI830->output[i].disabled = TRUE;
pI830->output[i].pipe = 0;
break;
case I830_OUTPUT_DVO:
case I830_OUTPUT_SDVO:
if (pI830->MonType1 & PIPE_DFP)
pI830->output[i].pipe = 0;
else if (pI830->MonType2 & PIPE_DFP)
pI830->output[i].pipe = 1;
else
pI830->output[i].disabled = TRUE;
pI830->output[i].pipe = 0;
break;
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled output type\n");
@ -1473,8 +1375,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
}
#if 0
pI830->CloneRefresh = 60; /* default to 60Hz */
if (xf86GetOptValInteger(pI830->Options, OPTION_CLONE_REFRESH,
&(pI830->CloneRefresh))) {
@ -1497,6 +1398,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
}
#endif
pI830->rotation = RR_Rotate_0;
if ((s = xf86GetOptValString(pI830->Options, OPTION_ROTATE))) {
@ -1672,8 +1574,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
}
PrintDisplayDeviceInfo(pScrn);
#if 0
if (xf86IsEntityShared(pScrn->entityList[0])) {
if (!I830IsPrimary(pScrn)) {
/* This could be made to work with a little more fiddling */
@ -1689,6 +1590,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, from, "Display is using Pipe %s\n",
pI830->pipe ? "B" : "A");
}
#endif
/* Alloc our pointers for the primary head */
if (I830IsPrimary(pScrn)) {
@ -2898,17 +2800,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
}
#endif
if (xf86IsEntityShared(pScrn->entityList[0])) {
/* PreInit failed on the second head, so make sure we turn it off */
if (I830IsPrimary(pScrn) && !pI830->entityPrivate->pScrn_2) {
if (pI830->pipe == 0) {
pI830->operatingDevices &= 0xFF;
} else {
pI830->operatingDevices &= 0xFF00;
}
}
}
pI830->starting = TRUE;
/* Alloc our pointers for the primary head */
@ -3295,6 +3186,7 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
int i;
DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
x, pI830->xoffset, y, pI830->yoffset);
@ -3305,9 +3197,9 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags)
pI830->AccelInfoRec->NeedToSync = FALSE;
}
i830PipeSetBase(pScrn, pI830->pipe, x, y);
if (pI830->Clone)
i830PipeSetBase(pScrn, !pI830->pipe, x, y);
for (i = 0; i < pI830->availablePipes; i++)
if (pI830->pipes[i].planeEnabled)
i830PipeSetBase(pScrn, i, x, y);
}
static void

View File

@ -492,45 +492,31 @@ I830RandRCrtcNotify (RRCrtcPtr crtc)
I830PipePtr pI830Pipe = &pI830->pipes[pipe];
int i, j;
DisplayModePtr pipeMode = &pI830Pipe->curMode;
int pipe_type;
x = pI830Pipe->x;
y = pI830Pipe->y;
rotation = RR_Rotate_0;
numOutputs = 0;
mode = NULL;
for (i = 0; i < pI830->num_outputs; i++)
{
output = &pI830->output[i];
/*
* Valid crtcs
*/
switch (output->type) {
case I830_OUTPUT_DVO:
case I830_OUTPUT_SDVO:
pipe_type = PIPE_DFP;
break;
case I830_OUTPUT_ANALOG:
pipe_type = PIPE_CRT;
break;
case I830_OUTPUT_LVDS:
pipe_type = PIPE_LFP;
break;
case I830_OUTPUT_TVOUT:
pipe_type = PIPE_TV;
break;
default:
pipe_type = PIPE_NONE;
break;
}
if (pI830->operatingDevices & (pipe_type << (pipe << 3)))
if (!output->disabled && output->pipe == pipe)
{
rrout = randrp->outputs[i];
outputs[numOutputs++] = rrout;
/*
* We make copies of modes, so pointer equality
* isn't sufficient
*/
for (j = 0; j < rrout->numModes; j++)
{
DisplayModePtr outMode = rrout->modes[j]->devPrivate;
if (I830ModesEqual(pipeMode, outMode))
{
mode = rrout->modes[j];
break;
}
}
}
}
@ -571,14 +557,7 @@ I830RandRCrtcSet (ScreenPtr pScreen,
}
else
{
CARD32 operatingDevices = pI830->operatingDevices;
if (pipe == 0)
pI830->operatingDevices &= ~0xff;
else
pI830->operatingDevices &= ~0xff00;
i830DisableUnusedFunctions (pScrn);
pI830->operatingDevices = operatingDevices;
}
randrp->modes[pipe] = display_mode;
}
@ -614,7 +593,6 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
int p;
int clone_types;
int crtc_types;
int pipe_type;
int pipe;
int subpixel;
DisplayModePtr modes, mode;
@ -644,7 +622,6 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
clone_types = ((1 << I830_OUTPUT_ANALOG) |
(1 << I830_OUTPUT_DVO) |
(1 << I830_OUTPUT_SDVO));
pipe_type = PIPE_DFP;
subpixel = SubPixelHorizontalRGB;
break;
case I830_OUTPUT_ANALOG:
@ -652,13 +629,11 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
clone_types = ((1 << I830_OUTPUT_ANALOG) |
(1 << I830_OUTPUT_DVO) |
(1 << I830_OUTPUT_SDVO));
pipe_type = PIPE_CRT;
subpixel = SubPixelNone;
break;
case I830_OUTPUT_LVDS:
crtc_types = (1 << 1);
clone_types = (1 << I830_OUTPUT_LVDS);
pipe_type = PIPE_LFP;
subpixel = SubPixelHorizontalRGB;
possibleOptions = (RROutputOptionScaleNone|
RROutputOptionScaleMaxAspect |
@ -669,32 +644,27 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
crtc_types = ((1 << 0) |
(1 << 1));
clone_types = (1 << I830_OUTPUT_TVOUT);
pipe_type = PIPE_TV;
subpixel = SubPixelNone;
break;
default:
crtc_types = 0;
clone_types = 0;
pipe_type = PIPE_NONE;
subpixel = SubPixelUnknown;
break;
}
ncrtc = 0;
pipe = -1;
crtc = NULL;
for (j = 0; j < pI830->availablePipes; j++)
if (!output->disabled)
{
#if 0
/* Can't flip outputs among crtcs yet */
if (crtc_types & (1 << j))
crtcs[ncrtc++] = randrp->crtcs[j];
#endif
if (pI830->operatingDevices & (pipe_type << (j << 3)))
{
pipe = j;
crtc = randrp->crtcs[j];
crtcs[ncrtc++] = crtc;
}
/* Can't flip outputs among crtcs yet */
ncrtc = 1;
pipe = output->pipe;
crtc = randrp->crtcs[pipe];
crtcs[0] = randrp->crtcs[pipe];
}
else
{
ncrtc = 0;
pipe = -1;
crtc = NULL;
}
if (!RROutputSetCrtcs (randrp->outputs[i], crtcs, ncrtc))
return FALSE;

View File

@ -722,7 +722,7 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen)
pPriv->brightness = 0;
pPriv->contrast = 64;
pPriv->saturation = 128;
pPriv->pipe = pI830->pipe; /* default to current pipe */
pPriv->pipe = 0; /* XXX must choose pipe wisely */
pPriv->linear = NULL;
pPriv->currentBuf = 0;
pPriv->gamma5 = 0xc0c0c0;
@ -3592,6 +3592,8 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode)
pPriv->overlayOK = TRUE;
#if 0
/* XXX Must choose pipe wisely */
/* ensure pipe is updated on mode switch */
if (!pI830->Clone) {
if (pPriv->pipe != pI830->pipe) {
@ -3600,6 +3602,7 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode)
pPriv->pipe = pI830->pipe;
}
}
#endif
if (!IS_I965G(pI830)) {
if (pPriv->pipe == 0) {
@ -3628,8 +3631,8 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode)
}
/* Check we have an LFP connected */
if ((pPriv->pipe == 1 && pI830->operatingDevices & (PIPE_LFP << 8)) ||
(pPriv->pipe == 0 && pI830->operatingDevices & PIPE_LFP) ) {
if (i830PipeHasType (pScrn, pPriv->pipe, I830_OUTPUT_LVDS))
{
size = pPriv->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
hsize = (size >> 16) & 0x7FF;
vsize = size & 0x7FF;