2 c_start.c - description
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your opinion) any later version.
13 #include <exec/types.h>
15 #include <aros/multiboot.h>
18 void com1_putc(char c
);
21 /* Convert the integer D to a string and save the string in BUF. If
22 BASE is equal to 'd', interpret that D is decimal, and if BASE is
23 equal to 'x', interpret that D is hexadecimal. */
24 static void itoa (char *buf
, int base
, int d
)
31 /* If %d is specified and D is minus, put `-' in the head. */
32 if (base
== 'd' && d
< 0)
41 /* Divide UD by DIVISOR until UD == 0. */
44 int remainder
= ud
% divisor
;
46 *p
++ = (remainder
< 10) ? remainder
+ '0' : remainder
+ 'a' - 10;
48 while (ud
/= divisor
);
66 static void _com1_putc(char c
)
75 /* Format a string and print it on the screen, just like the libc
77 void com1_printf(const char *format
, ...)
80 __builtin_varargs_start(ap
);
85 while ((c
= *format
++) != 0)
100 itoa (buf
, c
, __builtin_va_arg(ap
, int));
106 p
= __builtin_va_arg(ap
, char*);
116 _com1_putc(__builtin_va_arg(ap
, int));
121 __builtin_va_end(ap
);
124 ULONG
findMem(APTR ofw
, ULONG orig_MSR
)
126 ULONG
volatile *mem
=(APTR
)(16*1024*1024);
130 ULONG dev_handle
, res
, size
;
133 asm volatile("mfmsr %0":"=r"(msr
));
135 while(ofw
&& ((ULONG
)ofw
< 0x10000000))
137 asm volatile("mtmsr %0"::"r"(orig_MSR
));
140 res
= of_finddevice("/memory@0", &dev_handle
);
145 res
= of_getprop(dev_handle
, "reg", mem_info
, sizeof(mem_info
), &size
);
148 mem
= (ULONG
*)mem_info
[1];
153 asm volatile("mtmsr %0"::"r"(msr
));
157 void cstart(APTR load_addr
, APTR real_addr
, ULONG kernel_size
,
158 APTR residual
, APTR ofw
, ULONG orig_MSR
)
161 struct CallOS callos
;
164 Define CallOS on stack temporarly. It is allowed since Launch kernel
165 from this function while local variables remains reserved
170 ULONG mem_avail
; //=findMem(); /* Assume 16MB of ram */
171 com1_printf("\n%s\n",&core_id
);
173 com1_printf("\n[startup] load_addr : $%x"
174 "\n[startup] real_addr : $%x"
175 "\n[startup] kernel_size: %dKB"
176 "\n[startup] residual : $%x"
177 "\n[startup] ofw_iface : $%x\n",
178 load_addr
, real_addr
, (kernel_size
+1023) >> 10, residual
, ofw
);
180 mem_avail
= findMem(ofw
, orig_MSR
);
182 com1_printf("[startup] memory detected: %dMB\n",
186 Multiboot structure is forced to appear at physical address
187 location 0x00000008. It is allowable since the exception
188 vectors are at 0xfff00100 and will be fixed later. By this
189 time we create multiboot here.
191 struct multiboot
*mb
= (struct multiboot
*)0x8;
192 struct mb_mmap
*mmap
= (struct mb_mmap
*)(0x8 + sizeof(struct multiboot
));
194 /* Prepare multiboot structure */
195 mb
->flags
= MB_FLAGS_LDRNAME
198 mb
->loader_name
= "PowerPC bootloader";
200 mb
->mmap_addr
= (ULONG
)mmap
;
201 mb
->mmap_length
= ((mem_avail
> 16*1024*1024) ? 2 : 1) * sizeof(struct mb_mmap
);
204 Do mmap setup. Usually we have 1 or 2 entries, the
205 first is the DMA memory and the second is everything
208 mmap
[0].size
= sizeof(struct mb_mmap
) - 4;
209 mmap
[0].type
= MMAP_TYPE_RAM
;
210 mmap
[0].addr_low
= 0x4000;
211 mmap
[0].addr_high
= 0;
212 mmap
[0].len_low
= (ULONG
)real_addr
- 0x4000;
213 mmap
[0].len_high
= 0;
215 if (mem_avail
> 16*1024*1024)
217 mmap
[1].size
= sizeof(struct mb_mmap
) - 4;
218 mmap
[1].type
= MMAP_TYPE_RAM
;
219 mmap
[1].addr_low
= 16*1024*1024;
220 mmap
[1].addr_high
= 0;
221 mmap
[1].len_low
= mem_avail
- 16*1024*1024;
222 mmap
[1].len_high
= 0;
227 // cmain(MULTIBOOT_BOOTLOADER_MAGIC, (ULONG)mb);