Changeset 23749 in vbox
- Timestamp:
- Oct 14, 2009 9:18:53 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 53475
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/err.h
r23714 r23749 598 598 /** The VM was suspended while saving, don't resume execution. */ 599 599 #define VINF_SSM_LIVE_SUSPENDED 1864 600 /** Complex SSM field fed to SSMR3PutStruct or SSMR3GetStruct. Use the 601 * extended API. */ 602 #define VERR_SSM_COMPLEX_FIELD (-1864) 603 /** Invalid size of a SSM field with the specified transformation. */ 604 #define VERR_SSM_INVALID_FIELD_SIZE (-1865) 600 605 /** @} */ 601 606 -
trunk/include/VBox/ssm.h
r23709 r23749 96 96 97 97 98 /** Pointer to a structure field description. */ 99 typedef struct SSMFIELD *PSSMFIELD; 100 /** Pointer to a const structure field description. */ 101 typedef const struct SSMFIELD *PCSSMFIELD; 102 103 /** 104 * SSMFIELD Get/Put callback function. 105 * 106 * This is call for getting and putting the field it is associated with. It's 107 * up to the callback to work the saved state correctly. 108 * 109 * @returns VBox status code. 110 * 111 * @param pSSM The saved state handle. 112 * @param pField The field that is being processed. 113 * @param pvStruct Pointer to the structure. 114 * @param fFlags SSMSTRUCT_FLAGS_XXX. 115 * @param fGetOrPut True if getting, false if putting. 116 * @param pvUser The user argument specified to SSMR3GetStructEx or 117 * SSMR3PutStructEx. 118 */ 119 typedef DECLCALLBACK(int) FNSSMFIELDGETPUT(PSSMHANDLE pSSM, const struct SSMFIELD *pField, void *pvStruct, 120 uint32_t fFlags, bool fGetOrPut, void *pvUser); 121 /** Pointer to a SSMFIELD Get/Put callback. */ 122 typedef FNSSMFIELDGETPUT *PFNSSMFIELDGETPUT; 123 124 /** 125 * SSM field transformers. 126 * 127 * These are stored in the SSMFIELD::pfnGetPutOrTransformer and must therefore 128 * have values outside the valid pointer range. 129 */ 130 typedef enum SSMFIELDTRANS 131 { 132 /** Invalid. */ 133 SSMFIELDTRANS_INVALID = 0, 134 /** No transformation. */ 135 SSMFIELDTRANS_NO_TRANSFORMATION, 136 /** Guest context (GC) virtual address. */ 137 SSMFIELDTRANS_GCPTR, 138 /** Guest context (GC) physical address. */ 139 SSMFIELDTRANS_GCPHYS, 140 /** Ignorable Host context (HC) virtual address. See SSMFIELD_ENTRY_HCPTR. */ 141 SSMFIELDTRANS_HCPTR, 142 /** Ignorable field. See SSMFIELD_ENTRY_IGNORE. */ 143 SSMFIELDTRANS_IGNORE 144 } SSMFIELDTRANS; 145 98 146 /** 99 147 * A structure field description. 100 *101 * @todo Add an type field here for recording what's a GCPtr, GCPhys or anything102 * else that may change and is expected to continue to work.103 * @todo Later we need to add load transformations to this structure. I think a104 * callback with a number of default transformations in SIG_DEF style105 * would be good enough. The callback would take a user context from a new106 * SSMR3GetStruct parameter or something.107 148 */ 108 149 typedef struct SSMFIELD 109 150 { 151 /** Getter and putter callback or transformer index. */ 152 PFNSSMFIELDGETPUT pfnGetPutOrTransformer; 110 153 /** Field offset into the structure. */ 111 uint32_t off;154 uint32_t off; 112 155 /** The size of the field. */ 113 uint32_t cb;156 uint32_t cb; 114 157 } SSMFIELD; 115 /** Pointer to a structure field description. */ 116 typedef SSMFIELD *PSSMFIELD; 117 /** Pointer to a const structure field description. */ 118 typedef const SSMFIELD *PCSSMFIELD; 119 158 159 /** Emit a SSMFIELD array entry. 160 * @internal */ 161 #define SSMFIELD_ENTRY_INT(Type, Field, enmTransformer) \ 162 { \ 163 (PFNSSMFIELDGETPUT)(uintptr_t)(enmTransformer), \ 164 RT_OFFSETOF(Type, Field), \ 165 RT_SIZEOFMEMB(Type, Field) \ 166 } 120 167 /** Emit a SSMFIELD array entry. */ 121 #define SSMFIELD_ENTRY(Type, Field) { RT_OFFSETOF(Type, Field), RT_SIZEOFMEMB(Type, Field) }168 #define SSMFIELD_ENTRY(Type, Field) SSMFIELD_ENTRY_INT(Type, Field, SSMFIELDTRANS_NO_TRANSFORMATION) 122 169 /** Emit a SSMFIELD array entry for a RTGCPTR type. */ 123 #define SSMFIELD_ENTRY_GCPTR(Type, Field) SSMFIELD_ENTRY (Type, Field)170 #define SSMFIELD_ENTRY_GCPTR(Type, Field) SSMFIELD_ENTRY_INT(Type, Field, SSMFIELDTRANS_GCPTR) 124 171 /** Emit a SSMFIELD array entry for a RTGCPHYS type. */ 125 #define SSMFIELD_ENTRY_GCPHYS(Type, Field) SSMFIELD_ENTRY(Type, Field) 172 #define SSMFIELD_ENTRY_GCPHYS(Type, Field) SSMFIELD_ENTRY_INT(Type, Field, SSMFIELDTRANS_GCPHYS) 173 /** Emit a SSMFIELD array entry for a ring-0 or ring-3 pointer type that is 174 * of no real interest to the saved state. It follows the same save and restore 175 * rules as SSMFIELD_ENTRY_IGNORE. */ 176 #define SSMFIELD_ENTRY_HCPTR(Type, Field) SSMFIELD_ENTRY_INT(Type, Field, SSMFIELDTRANS_HCPTR) 177 /** Emit a SSMFIELD array entry for a field that can be ignored. 178 * It is stored if SSMSTRUCT_FLAGS_DONT_IGNORE is specified to SSMR3PutStructEx. 179 * It is skipped if SSMSTRUCT_FLAGS_DONT_IGNORE is specified to 180 * SSMR3GetStructEx, the structure member is never touched on restore. */ 181 #define SSMFIELD_ENTRY_IGNORE(Type, Field) SSMFIELD_ENTRY_INT(Type, Field, SSMFIELDTRANS_IGNORE) 182 /** Emit a SSMFIELD array entry for a field with a custom callback. */ 183 #define SSMFIELD_ENTRY_CALLBACK(Type, Field, pfnGetPut) \ 184 { (pfnGetPut), RT_OFFSETOF(Type, Field), RT_SIZEOFMEMB(Type, Field) } 126 185 /** Emit the terminating entry of a SSMFIELD array. */ 127 #define SSMFIELD_ENTRY_TERM() { UINT32_MAX, UINT32_MAX } 128 186 #define SSMFIELD_ENTRY_TERM() { (PFNSSMFIELDGETPUT)(uintptr_t)SSMFIELDTRANS_INVALID, UINT32_MAX, UINT32_MAX } 187 188 189 /** @name SSMR3GetStructEx and SSMR3PutStructEx flags. 190 * @{ */ 191 /** The field descriptors must exactly cover the entire struct, A to Z. */ 192 #define SSMSTRUCT_FLAGS_FULL_STRUCT RT_BIT_32(0) 193 /** Do not ignore any ignorable fields. */ 194 #define SSMSTRUCT_FLAGS_DONT_IGNORE RT_BIT_32(1) 195 /** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host pointers. */ 196 #define SSMSTRUCT_FLAGS_MEM_BAND_AID (SSMSTRUCT_FLAGS_DONT_IGNORE | SSMSTRUCT_FLAGS_FULL_STRUCT) 197 /** @} */ 129 198 130 199 … … 763 832 */ 764 833 VMMR3DECL(int) SSMR3PutStruct(PSSMHANDLE pSSM, const void *pvStruct, PCSSMFIELD paFields); 834 VMMR3DECL(int) SSMR3PutStructEx(PSSMHANDLE pSSM, const void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser); 765 835 VMMR3DECL(int) SSMR3PutBool(PSSMHANDLE pSSM, bool fBool); 766 836 VMMR3DECL(int) SSMR3PutU8(PSSMHANDLE pSSM, uint8_t u8); … … 796 866 */ 797 867 VMMR3DECL(int) SSMR3GetStruct(PSSMHANDLE pSSM, void *pvStruct, PCSSMFIELD paFields); 868 VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser); 798 869 VMMR3DECL(int) SSMR3GetBool(PSSMHANDLE pSSM, bool *pfBool); 799 870 VMMR3DECL(int) SSMR3GetU8(PSSMHANDLE pSSM, uint8_t *pu8); -
trunk/src/VBox/VMM/SSM.cpp
r23729 r23749 3163 3163 pCur++) 3164 3164 { 3165 rc = ssmR3DataWrite(pSSM, (uint8_t *)pvStruct + pCur->off, pCur->cb); 3166 if (RT_FAILURE(rc)) 3167 return rc; 3165 uint8_t const *pbField = (uint8_t const *)pvStruct + pCur->off; 3166 switch ((uintptr_t)pCur->pfnGetPutOrTransformer) 3167 { 3168 case SSMFIELDTRANS_NO_TRANSFORMATION: 3169 rc = ssmR3DataWrite(pSSM, pbField, pCur->cb); 3170 break; 3171 3172 case SSMFIELDTRANS_GCPTR: 3173 AssertMsgReturn(pCur->cb == sizeof(RTGCPTR), ("%#x\n", pCur->cb), VERR_SSM_INVALID_FIELD_SIZE); 3174 rc = SSMR3PutGCPtr(pSSM, *(PRTGCPTR)pbField); 3175 break; 3176 3177 case SSMFIELDTRANS_GCPHYS: 3178 AssertMsgReturn(pCur->cb == sizeof(RTGCPHYS), ("%#x\n", pCur->cb), VERR_SSM_INVALID_FIELD_SIZE); 3179 rc = SSMR3PutGCPhys(pSSM, *(PRTGCPHYS)pbField); 3180 break; 3181 3182 default: 3183 AssertMsgFailedReturn(("%#x\n", pCur->pfnGetPutOrTransformer), VERR_SSM_COMPLEX_FIELD); 3184 } 3168 3185 } 3169 3186 … … 5511 5528 AssertMsgFailedReturn(("u32Magic=%#RX32\n", u32Magic), VERR_SSM_STRUCTURE_MAGIC); 5512 5529 5513 /* put the fields */5530 /* get the fields */ 5514 5531 for (PCSSMFIELD pCur = paFields; 5515 5532 pCur->cb != UINT32_MAX && pCur->off != UINT32_MAX; 5516 5533 pCur++) 5517 5534 { 5518 rc = ssmR3DataRead(pSSM, (uint8_t *)pvStruct + pCur->off, pCur->cb); 5519 if (RT_FAILURE(rc)) 5520 return rc; 5535 uint8_t *pbField = (uint8_t *)pvStruct + pCur->off; 5536 switch ((uintptr_t)pCur->pfnGetPutOrTransformer) 5537 { 5538 case SSMFIELDTRANS_NO_TRANSFORMATION: 5539 rc = ssmR3DataRead(pSSM, pbField, pCur->cb); 5540 break; 5541 5542 case SSMFIELDTRANS_GCPTR: 5543 AssertMsgReturn(pCur->cb == sizeof(RTGCPTR), ("%#x\n", pCur->cb), VERR_SSM_INVALID_FIELD_SIZE); 5544 rc = SSMR3GetGCPtr(pSSM, (PRTGCPTR)pbField); 5545 break; 5546 5547 case SSMFIELDTRANS_GCPHYS: 5548 AssertMsgReturn(pCur->cb == sizeof(RTGCPHYS), ("%#x\n", pCur->cb), VERR_SSM_INVALID_FIELD_SIZE); 5549 rc = SSMR3GetGCPhys(pSSM, (PRTGCPHYS)pbField); 5550 break; 5551 5552 default: 5553 AssertMsgFailedReturn(("%#x\n", pCur->pfnGetPutOrTransformer), VERR_SSM_COMPLEX_FIELD); 5554 } 5521 5555 } 5522 5556
Note:
See TracChangeset
for help on using the changeset viewer.