9 /* NOTE be very careful with static variables. No relocations are
10 * being performed so static variables with initialized pointers will
11 * point to the wrong locations, unless this file is loaded at just
14 /* Data and functions in head.S */
15 extern void uart_tx_byte(int c);
17 static void putchar(int c)
27 #define LONG_SHIFT ((int)((sizeof(unsigned long)*CHAR_BIT) - 4))
28 #define INT_SHIFT ((int)((sizeof(unsigned int)*CHAR_BIT) - 4))
29 #define SHRT_SHIFT ((int)((sizeof(unsigned short)*CHAR_BIT) - 4))
30 #define CHAR_SHIFT ((int)((sizeof(unsigned char)*CHAR_BIT) - 4))
32 /**************************************************************************
36 %x - 4 bytes int (8 hex digits, lower case)
37 %X - 4 bytes int (8 hex digits, upper case)
38 %lx - 8 bytes long (16 hex digits, lower case)
39 %lX - 8 bytes long (16 hex digits, upper case)
40 %hx - 2 bytes int (4 hex digits, lower case)
41 %hX - 2 bytes int (4 hex digits, upper case)
42 %hhx - 1 byte int (2 hex digits, lower case)
43 %hhX - 1 byte int (2 hex digits, upper case)
44 - optional # prefixes 0x or 0X
48 Note: width specification not supported
49 **************************************************************************/
50 static void printf(const char *fmt, ...)
55 for ( ; *fmt != '\0'; ++fmt) {
61 for(p = va_arg(args, char *); *p != '\0'; p++)
64 else { /* Length of item is bounded */
65 char tmp[40], *q = tmp;
66 int shift = INT_SHIFT;
71 else if (*fmt == 'h') {
81 * Before each format q points to tmp buffer
82 * After each format q points past end of item
84 if ((*fmt | 0x20) == 'x') {
85 /* With x86 gcc, sizeof(long) == sizeof(int) */
88 if (shift > INT_SHIFT) {
89 h = va_arg(args, unsigned long);
91 h = va_arg(args, unsigned int);
93 ncase = (*fmt & 0x20);
94 for ( ; shift >= 0; shift -= 4)
95 *q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
97 else if (*fmt == 'd') {
100 if (shift > INT_SHIFT) {
101 i = va_arg(args, long);
103 i = va_arg(args, int);
109 p = q; /* save beginning of digits */
111 *q++ = '0' + (i % 10);
114 /* reverse digits, stop in middle */
115 r = q; /* don't alter q */
122 else if (*fmt == 'c')
123 *q++ = va_arg(args, int);
126 /* now output the saved string */
127 for (p = tmp; p < q; ++p)
134 void *memcpy(void *vdest, void *vsrc, size_t size)
136 unsigned char *dest = vdest, *src = vsrc;
138 for(i = 0; i < size; i++) {
144 int memcmp(void *vs1, void *vs2, size_t size)
146 unsigned char *s1 =vs1, *s2=vs2;
148 for(i = 0; i < size; i++, s1++, s2++) {
156 void strappend(char *dest, const char *src, size_t max)
159 /* Walk to the end of the destination string */
160 for(len = 0; len < max; len++) {
161 if (dest[len] == '\0')
164 /* Walk through the source string and append it */
165 for(i = 0; (i + len) < max; i++) {
168 dest[len + i] = src[i];
171 /* Now null terminate the string */
178 static struct ia64_boot_param {
179 uint64_t command_line; /* physical address of command line arguments */
180 uint64_t efi_systab; /* physical address of EFI system table */
181 uint64_t efi_memmap; /* physical address of EFI memory map */
182 uint64_t efi_memmap_size; /* size of EFI memory map */
183 uint64_t efi_memdesc_size; /* size of an EFI memory map descriptor */
184 uint32_t efi_memdesc_version; /* memory descriptor version */
186 uint16_t num_cols; /* number of columns on console output device */
187 uint16_t num_rows; /* number of rows on console output device */
188 uint16_t orig_x; /* cursor's x position */
189 uint16_t orig_y; /* cursor's y position */
191 uint64_t fpswa; /* physical address of the fpswa interface */
192 uint64_t initrd_start;
193 uint64_t initrd_size;
194 } bp = { 0, 0, 0, 0, 0, 0, { 80, 24, 0, 0 }, 0, 0, 0 };
196 static void append_command_line(char *arg)
198 strappend((char *)bp.command_line, " ", CMDLINE_MAX);
199 strappend((char *)bp.command_line, arg, CMDLINE_MAX);
202 static void convert_ia64_boot_params(struct ia64_boot_param *orig_bp)
204 /* Copy the parameters I have no clue about */
205 bp.efi_systab = orig_bp->efi_systab;
206 bp.efi_memmap = orig_bp->efi_memmap;
207 bp.efi_memmap_size = orig_bp->efi_memmap_size;
208 bp.efi_memdesc_size = orig_bp->efi_memdesc_size;
209 bp.efi_memdesc_version = orig_bp->efi_memdesc_version;
210 bp.console_info.num_cols = orig_bp->console_info.num_cols;
211 bp.console_info.num_rows = orig_bp->console_info.num_rows;
212 bp.console_info.orig_x = orig_bp->console_info.orig_x;
213 bp.console_info.orig_y = orig_bp->console_info.orig_y;
214 bp.fpswa = orig_bp->fpswa;
215 /* If a ramdisk was supplied and I didn't original have one,
218 if (orig_bp->initrd_size && (!bp.initrd_size)) {
219 bp.initrd_start = orig_bp->initrd_start;
220 bp.initrd_size = orig_bp->initrd_size;
222 /* If a command line was supplied append it */
223 if (orig_bp->command_line) {
224 append_command_line((char *)(orig_bp->command_line));
228 static void convert_bhdr_params(Elf_Bhdr *bhdr)
230 unsigned char *note, *end;
231 char *ldr_name, *ldr_version, *firmware;
233 ldr_name = ldr_version = firmware = 0;
235 note = ((char *)bhdr) + sizeof(*bhdr);
236 end = ((char *)bhdr) + bhdr->b_size;
239 unsigned char *n_name, *n_desc, *next;
240 hdr = (Elf_Nhdr *)note;
241 n_name = note + sizeof(*hdr);
242 n_desc = n_name + ((hdr->n_namesz + 3) & ~3);
243 next = n_desc + ((hdr->n_descsz + 3) & ~3);
247 printf("n_type: %x n_name(%d): n_desc(%d): \n",
248 hdr->n_type, hdr->n_namesz, hdr->n_descsz);
251 if (hdr->n_namesz == 0) {
252 switch(hdr->n_type) {
253 case EBN_FIRMWARE_TYPE:
256 case EBN_BOOTLOADER_NAME:
259 case EBN_BOOTLOADER_VERSION:
260 ldr_version = n_desc;
262 case EBN_COMMAND_LINE:
263 append_command_line(n_desc);
267 else if ((hdr->n_namesz == 10) &&
268 (memcmp(n_name, "Etherboot", 10) == 0)) {
269 switch(hdr->n_type) {
272 uint64_t *systabp = (void *)n_desc;
273 bp.efi_systab = *systabp;
278 uint64_t *fpswap = (void *)n_desc;
282 case EB_IA64_CONINFO:
283 memcpy(&bp.console_info, n_desc, sizeof(bp.console_info));
290 uint64_t descriptor_size;
291 uint64_t descriptor_version;
293 } *map = (void *)n_desc;
294 bp.efi_memmap = (uint64_t)&map->map;
295 bp.efi_memmap_size = map->map_size;
296 bp.efi_memdesc_size = map->descriptor_size;
297 bp.efi_memdesc_version = map->descriptor_version;
304 if (ldr_name && ldr_version) {
305 printf("Loader: %s version: %s\n",
306 ldr_name, ldr_version);
309 printf("Firmware: %s\n",
314 void *convert_params(unsigned long arg1, unsigned long r28,
315 struct image_parameters *params)
317 struct ia64_boot_param *orig_bp;
318 Elf_Bhdr *bhdr = (Elf_Bhdr*)arg1;
320 /* handle the options I can easily deal with */
321 bp.command_line = (unsigned long)¶ms->cmdline;
322 bp.initrd_start = params->initrd_start;
323 bp.initrd_size = params->initrd_size;
325 orig_bp = (struct ia64_boot_param *)r28;
326 if (bhdr->b_signature == 0x0E1FB007) {
327 convert_bhdr_params(bhdr);
330 convert_ia64_boot_params(orig_bp);