From patchwork Mon Dec 23 19:43:32 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaro Koskinen X-Patchwork-Id: 304847 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id E6F052C00A8 for ; Tue, 24 Dec 2013 06:44:05 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757814Ab3LWToB (ORCPT ); Mon, 23 Dec 2013 14:44:01 -0500 Received: from filtteri6.pp.htv.fi ([213.243.153.189]:48904 "EHLO filtteri6.pp.htv.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757836Ab3LWTn4 (ORCPT ); Mon, 23 Dec 2013 14:43:56 -0500 Received: from localhost (localhost [127.0.0.1]) by filtteri6.pp.htv.fi (Postfix) with ESMTP id 5D0B656F61A; Mon, 23 Dec 2013 21:43:55 +0200 (EET) X-Virus-Scanned: Debian amavisd-new at pp.htv.fi Received: from smtp5.welho.com ([213.243.153.39]) by localhost (filtteri6.pp.htv.fi [213.243.153.189]) (amavisd-new, port 10024) with ESMTP id xFzHKP89wiVz; Mon, 23 Dec 2013 21:43:50 +0200 (EET) Received: from blackmetal.bb.dnainternet.fi (91-145-91-118.bb.dnainternet.fi [91.145.91.118]) by smtp5.welho.com (Postfix) with ESMTP id D51245BC010; Mon, 23 Dec 2013 21:43:47 +0200 (EET) From: Aaro Koskinen To: sparclinux@vger.kernel.org Cc: Aaro Koskinen Subject: [PATCH v2 10/11] tilo: allocate kernel memory dynamically on sun4u Date: Mon, 23 Dec 2013 21:43:32 +0200 Message-Id: <1387827813-8279-11-git-send-email-aaro.koskinen@iki.fi> X-Mailer: git-send-email 1.8.5.1 In-Reply-To: <1387827813-8279-1-git-send-email-aaro.koskinen@iki.fi> References: <1387827813-8279-1-git-send-email-aaro.koskinen@iki.fi> Sender: sparclinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: sparclinux@vger.kernel.org Allocate memory for kernel image dynamically on sun4u. This allows to boot bigger modern day kernels. External root image can be used "in-place" from TILO image. Signed-off-by: Aaro Koskinen --- tilo/tilo.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 112 insertions(+), 13 deletions(-) diff --git a/tilo/tilo.c b/tilo/tilo.c index d2fcd97b525f..9ed4091e0cdd 100644 --- a/tilo/tilo.c +++ b/tilo/tilo.c @@ -171,6 +171,69 @@ extern struct ImageInfo image_table[4]; /* Sun4 kernel, Sun4c/d/m kernel, Sun4u #define HDRS_TAG (('H'<<24) | ('d'<<16) | ('r'<<8) | 'S') +static char *sun4u_memory_find (unsigned int len) +{ + int n, node, i; + struct p1275_mem { + unsigned long long phys; + unsigned long long size; + } *p = (struct p1275_mem *)0; + unsigned int virt = 0x40000000; + unsigned long long phys = 0, phys_base; + + p = (struct p1275_mem *)malloc(2048); + + node = prom_finddevice("/memory"); + + n = prom_getproplen(node, "available"); + + if (!n || n == -1 || + prom_getproperty(node, "available", (char *)p, 2048) == -1) { + free (p); + printf("Could not get available property\n"); + return (char *)0; + } + + phys = 0; + n /= sizeof(*p); + + phys_base = ~(unsigned long long)0; + for (i = 0; i < n; i++) { + if (p[i].phys < phys_base) + phys_base = p[i].phys; + } + + for (i = 0; i < n; i++) { + /* Do not mess with first 16 Megs of memory */ + if (p[i].phys == phys_base) { + if (p[i].size <= 0x1000000) + continue; + p[i].phys += 0x1000000; + p[i].size -= 0x1000000; + } + + if (p[i].size >= len) { + phys = p[i].phys; + break; + } + } + + free (p); + + if (!phys) { + printf("Could not find any available memory\n"); + return (char *)0; + } + + if (prom_map(PROM_MAP_DEFAULT, (unsigned long long)len, virt, phys) == + -1) { + printf("Could not map memory\n"); + return (char *)0; + } + + return (char *)virt + 0x4000; +} + void parse_executable(char *base, int image_len) { union { @@ -275,10 +338,11 @@ void parse_executable(char *base, int image_len) char *my_main (struct linux_romvec *promvec, void *cifh, void *cifs) { -char *orig_code,*moved_code,*moved_ramdisk,*moved_kernel,*kernel_base; +char *orig_code,*moved_code,*moved_ramdisk = NULL,*moved_kernel,*kernel_base; unsigned *p,*q = NULL; int kernel_number; char *kernel_end, *kernel_limit; +int move_ramdisk; prom_init(promvec, cifh, cifs); @@ -307,21 +371,55 @@ char *kernel_end, *kernel_limit; } orig_code = (char*) 0x4000; - moved_code = (char*) MOVED_BASE; - moved_ramdisk = (char*)((long)(moved_code - image_table[ROOT_IMAGE].packed_len) & ~0xfff); - moved_kernel = (char*)((long)(moved_ramdisk - image_table[kernel_number].packed_len) & ~0xfff); + + /* + * On sun4u we can allocate more memory and relocate the kernel. + */ + if (kernel_number == SUN4U_KERNEL) { + unsigned int size; + + for (size = 64 * 1024 * 1024; size >= 4 * 1024 * 1024; + size -= 4 * 1024 * 1024) { + kernel_base = sun4u_memory_find(size); + if (kernel_base) + break; + } + if (!kernel_base) + goto no_mem; + kernel_limit = kernel_base + size; + gzminp = (unsigned char *)orig_code + + image_table[kernel_number].packed_start; + if (image_table[ROOT_IMAGE].packed_len) + image_table[kernel_number].root_start = (unsigned)orig_code + + image_table[ROOT_IMAGE].packed_start + 0x400000; + else + image_table[kernel_number].root_start = 0; + move_ramdisk = 0; + } else { +no_mem: + move_ramdisk = 1; + moved_code = (char*)MOVED_BASE; + moved_ramdisk = (char*)((long)(moved_code - + image_table[ROOT_IMAGE].packed_len) & ~0xfff); + moved_kernel = (char*)((long)(moved_ramdisk - + image_table[kernel_number].packed_len) & ~0xfff); #ifdef TILO_DEBUG - printf("Locations: moved_code=%x moved_ramdisk=%x moved_kernel=%x\n", - moved_code, moved_ramdisk, moved_kernel); + printf("Locations: moved_code=%x moved_ramdisk=%x moved_kernel=%x\n", + moved_code, moved_ramdisk, moved_kernel); #endif - memmove (moved_ramdisk, orig_code + image_table[ROOT_IMAGE].packed_start, image_table[ROOT_IMAGE].packed_len); - memmove (moved_kernel, orig_code + image_table[kernel_number].packed_start, image_table[kernel_number].packed_len); + memmove(moved_ramdisk, orig_code + image_table[ROOT_IMAGE].packed_start, + image_table[ROOT_IMAGE].packed_len); + memmove(moved_kernel, + orig_code + image_table[kernel_number].packed_start, + image_table[kernel_number].packed_len); + + gzminp = (unsigned char *)moved_kernel; /* decompress kernel */ + kernel_base = (char*) 0x4000; + kernel_limit = moved_kernel; + } - gzminp = (unsigned char *)moved_kernel; /* decompress kernel */ - kernel_base = (char*) 0x4000; kernel_end = kernel_base + ((image_table[kernel_number].unpacked_len + 0xfff) & ~0xfff); - kernel_limit = moved_kernel; if (kernel_end > kernel_limit) { printf("No space to decompress the kernel.\n"); @@ -375,8 +473,9 @@ char *kernel_end, *kernel_limit; q[5] = image_table[ROOT_IMAGE].packed_len; /* move root image */ - memmove ((void*)(image_table[kernel_number].root_start & 0x3fffff), - moved_ramdisk, image_table[ROOT_IMAGE].packed_len); + if (move_ramdisk) + memmove ((void*)(image_table[kernel_number].root_start & 0x3fffff), + moved_ramdisk, image_table[ROOT_IMAGE].packed_len); #ifdef TILO_DEBUG printf("Returning from my_main() with address %x\n", kernel_base); #endif