152,9 → 152,25 |
/** |
* Performs sun4u-specific initialization. The components are expected |
* to be already copied and boot allocator initialized. |
* |
* @param base kernel base virtual address |
* @param top virtual address above which the boot allocator |
* can make allocations |
*/ |
static void bootstrap_sun4u(void) |
static void bootstrap_sun4u(void *base, unsigned int top) |
{ |
void *balloc_base; |
|
/* |
* Claim and map the physical memory for the boot allocator. |
* Initialize the boot allocator. |
*/ |
balloc_base = base + ALIGN_UP(top, PAGE_SIZE); |
(void) ofw_claim_phys(bootinfo.physmem_start + balloc_base, |
BALLOC_MAX_SIZE); |
(void) ofw_map(balloc_base, balloc_base, BALLOC_MAX_SIZE, -1); |
balloc_init(&bootinfo.ballocs, (uintptr_t)balloc_base); |
|
printf("\nCanonizing OpenFirmware device tree..."); |
bootinfo.ofw_root = ofw_tree_build(); |
printf("done.\n"); |
177,12 → 193,35 |
*/ |
static void bootstrap_sun4v(void) |
{ |
/* |
* When SILO booted, the OBP had established a virtual to physical |
* memory mapping. This mapping is not an identity (because the |
* physical memory starts on non-zero address) - this is not |
* surprising. But! The mapping even does not map virtual address |
* 0 onto the starting address of the physical memory, but onto an |
* address which is 0x400000 bytes higher. The reason is that the |
* OBP had already used the memory just at the beginning of the |
* physical memory, so that memory cannot be used by SILO (nor |
* bootloader). As for now, we solve it by a nasty workaround: |
* we pretend that the physical memory starts 0x400000 bytes further |
* than it actually does (and hence pretend that the physical memory |
* is 0x400000 bytes smaller). Of course, the value 0x400000 will most |
* probably depend on the machine and OBP version (the workaround now |
* works on Simics). A solution would be to inspect the "available" |
* property of the "/memory" node to find out which parts of memory |
* are used by OBP and redesign the algorithm of copying |
* kernel/init tasks/ramdisk from the bootable image to memory |
* (which we must do anyway because of issues with claiming the memory |
* on Serengeti). |
*/ |
bootinfo.physmem_start += 0x400000; |
bootinfo.memmap.zones[0].start += 0x400000; |
bootinfo.memmap.zones[0].size -= 0x400000; |
} |
|
void bootstrap(void) |
{ |
void *base = (void *) KERNEL_VIRTUAL_ADDRESS; |
void *balloc_base; |
unsigned int top = 0; |
int i, j; |
|
317,19 → 356,9 |
memcpy(base, components[0].start, components[0].size); |
printf("done.\n"); |
|
/* |
* Claim and map the physical memory for the boot allocator. |
* Initialize the boot allocator. |
*/ |
balloc_base = base + ALIGN_UP(top, PAGE_SIZE); |
(void) ofw_claim_phys(bootinfo.physmem_start + balloc_base, |
BALLOC_MAX_SIZE); |
(void) ofw_map(balloc_base, balloc_base, BALLOC_MAX_SIZE, -1); |
balloc_init(&bootinfo.ballocs, (uintptr_t)balloc_base); |
|
/* perform architecture-specific initialization */ |
if (architecture == COMPATIBLE_SUN4U) { |
bootstrap_sun4u(); |
bootstrap_sun4u(base, top); |
} else if (architecture == COMPATIBLE_SUN4V) { |
bootstrap_sun4v(); |
} else { |