Move modify_adv() into common code
[profile/ivi/syslinux.git] / libinstaller / syslxint.h
1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
4  *
5  *   This program is free software; you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8  *   Boston MA 02111-1307, USA; either version 2 of the License, or
9  *   (at your option) any later version; incorporated herein by reference.
10  *
11  * ----------------------------------------------------------------------- */
12
13 #ifndef SYSLXINT_H
14 #define SYSLXINT_H
15
16 #include "syslinux.h"
17
18 #if defined(__386__) || defined(__i386__) || defined(__x86_64__)
19 # define X86_MEM 1              /* Littleendian and unaligned safe */
20 #else
21 # define X86_MEM 0
22 #endif
23
24 /*
25  * Access functions for littleendian numbers, possibly misaligned.
26  */
27 static inline uint8_t get_8(const uint8_t * p)
28 {
29     return *p;
30 }
31
32 static inline uint16_t get_16(const uint16_t * p)
33 {
34 #if X86_MEM
35     /* Littleendian and unaligned-capable */
36     return *p;
37 #else
38     const uint8_t *pp = (const uint8_t *)p;
39     return pp[0] + ((uint16_t)pp[1] << 8);
40 #endif
41 }
42
43 static inline uint32_t get_32(const uint32_t * p)
44 {
45 #if X86_MEM
46     /* Littleendian and unaligned-capable */
47     return *p;
48 #else
49     const uint16_t *pp = (const uint16_t *)p;
50     return get_16(pp[0]) + (uint32_t)get_16(pp[1]);
51 #endif
52 }
53
54 static inline uint64_t get_64(const uint64_t * p)
55 {
56 #if X86_MEM
57     /* Littleendian and unaligned-capable */
58     return *p;
59 #else
60     const uint32_t *pp = (const uint32_t *)p;
61     return get_32(pp[0]) + (uint64_t)get_32(pp[1]);
62 #endif
63 }
64
65 static inline void set_8(uint8_t *p, uint8_t v)
66 {
67     *p = v;
68 }
69
70 static inline void set_16(uint16_t *p, uint16_t v)
71 {
72 #if X86_MEM
73     /* Littleendian and unaligned-capable */
74     *p = v;
75 #else
76     uint8_t *pp = (uint8_t *) p;
77     pp[0] = (v & 0xff);
78     pp[1] = ((v >> 8) & 0xff);
79 #endif
80 }
81
82 static inline void set_32(uint32_t *p, uint32_t v)
83 {
84 #if X86_MEM
85     /* Littleendian and unaligned-capable */
86     *p = v;
87 #else
88     uint8_t *pp = (uint8_t *) p;
89     pp[0] = (v & 0xff);
90     pp[1] = ((v >> 8) & 0xff);
91     pp[2] = ((v >> 16) & 0xff);
92     pp[3] = ((v >> 24) & 0xff);
93 #endif
94 }
95
96 static inline void set_64(uint64_t *p, uint64_t v)
97 {
98 #if X86_MEM
99     /* Littleendian and unaligned-capable */
100     *p = v;
101 #else
102     uint32_t *pp = (uint32_t *) p;
103     set_32(pp[0], v);
104     set_32(pp[1], v >> 32);
105 #endif
106 }
107
108 /*
109  * Special handling for the MS-DOS derivative: syslinux_ldlinux
110  * is a "far" object...
111  */
112 #ifdef __MSDOS__
113
114 extern uint16_t ldlinux_seg;    /* Defined in dos/syslinux.c */
115
116 static inline __attribute__ ((const))
117 uint16_t ds(void)
118 {
119     uint16_t v;
120     asm("movw %%ds,%0":"=rm"(v));
121     return v;
122 }
123
124 static inline void *set_fs(const void *p)
125 {
126     uint16_t seg;
127
128     seg = ldlinux_seg + ((size_t) p >> 4);
129     asm volatile ("movw %0,%%fs"::"rm" (seg));
130     return (void *)((size_t) p & 0xf);
131 }
132
133 uint8_t get_8_sl(const uint8_t * p);
134 uint16_t get_16_sl(const uint16_t * p);
135 uint32_t get_32_sl(const uint32_t * p);
136 uint64_t get_64_sl(const uint64_t * p);
137 void set_8_sl(uint8_t * p, uint8_t v);
138 void set_16_sl(uint16_t * p, uint16_t v);
139 void set_32_sl(uint32_t * p, uint32_t v);
140 void set_64_sl(uint64_t * p, uint64_t v);
141 void memcpy_to_sl(void *dst, const void *src, size_t len);
142
143 #else
144
145 /* Sane system ... */
146 #define get_8_sl(x)             get_8(x)
147 #define get_16_sl(x)            get_16(x)
148 #define get_32_sl(x)            get_32(x)
149 #define get_64_sl(x)            get_64(x)
150 #define set_8_sl(x,y)           set_8(x,y)
151 #define set_16_sl(x,y)          set_16(x,y)
152 #define set_32_sl(x,y)          set_32(x,y)
153 #define set_64_sl(x,y)          set_64(x,y)
154 #define memcpy_to_sl(d,s,l)     memcpy(d,s,l)
155
156 #endif
157
158 #define LDLINUX_MAGIC   0x3eb202fe
159
160 /* Patch area for disk-based installers */
161 struct patch_area {
162     uint32_t magic;             /* LDLINUX_MAGIC */
163     uint32_t instance;          /* Per-version value */
164     uint16_t data_sectors;
165     uint16_t adv_sectors;
166     uint32_t dwords;
167     uint32_t checksum;
168     uint16_t maxtransfer;
169     uint16_t epaoffset;         /* Pointer to the extended patch area */
170 };
171
172 struct ext_patch_area {
173     uint16_t advptroffset;      /* ADV pointers */
174     uint16_t diroffset;         /* Current directory field */
175     uint16_t dirlen;            /* Length of current directory field */
176     uint16_t subvoloffset;      /* Subvolume field */
177     uint16_t subvollen;         /* Length of subvolume field */
178     uint16_t secptroffset;      /* Sector extent pointers */
179     uint16_t secptrcnt;         /* Number of sector extent pointers */
180
181     uint16_t sect1ptr0;         /* Boot sector offset of sector 1 ptr LSW */
182     uint16_t sect1ptr1;         /* Boot sector offset of sector 1 ptr MSW */
183     uint16_t raidpatch;         /* Boot sector RAID mode patch pointer */
184 };
185
186 /* Sector extent */
187 struct syslinux_extent {
188     uint64_t lba;
189     uint16_t len;
190 } __attribute__((packed));
191
192 /* FAT bootsector format, also used by other disk-based derivatives */
193 struct boot_sector {
194     uint8_t bsJump[3];
195     char bsOemName[8];
196     uint16_t bsBytesPerSec;
197     uint8_t bsSecPerClust;
198     uint16_t bsResSectors;
199     uint8_t bsFATs;
200     uint16_t bsRootDirEnts;
201     uint16_t bsSectors;
202     uint8_t bsMedia;
203     uint16_t bsFATsecs;
204     uint16_t bsSecPerTrack;
205     uint16_t bsHeads;
206     uint32_t bsHiddenSecs;
207     uint32_t bsHugeSectors;
208
209     union {
210         struct {
211             uint8_t DriveNumber;
212             uint8_t Reserved1;
213             uint8_t BootSignature;
214             uint32_t VolumeID;
215             char VolumeLabel[11];
216             char FileSysType[8];
217             uint8_t Code[448];
218         } __attribute__ ((packed)) bs16;
219         struct {
220             uint32_t FATSz32;
221             uint16_t ExtFlags;
222             uint16_t FSVer;
223             uint32_t RootClus;
224             uint16_t FSInfo;
225             uint16_t BkBootSec;
226             uint8_t Reserved0[12];
227             uint8_t DriveNumber;
228             uint8_t Reserved1;
229             uint8_t BootSignature;
230             uint32_t VolumeID;
231             char VolumeLabel[11];
232             char FileSysType[8];
233             uint8_t Code[420];
234         } __attribute__ ((packed)) bs32;
235     } __attribute__ ((packed));
236
237     uint16_t bsSignature;
238 } __attribute__ ((packed));
239
240 #define bsHead      bsJump
241 #define bsHeadLen   offsetof(struct boot_sector, bsBytesPerSec)
242 #define bsCode      bs32.Code   /* The common safe choice */
243 #define bsCodeLen   (offsetof(struct boot_sector, bsSignature) - \
244                      offsetof(struct boot_sector, bsCode))
245
246 #endif /* SYSLXINT_H */