From owner-p4-projects@FreeBSD.ORG Mon Feb 18 16:26:34 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 461C016A469; Mon, 18 Feb 2008 16:26:34 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0B1CD16A420 for ; Mon, 18 Feb 2008 16:26:34 +0000 (UTC) (envelope-from raj@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id F0A2613C478 for ; Mon, 18 Feb 2008 16:26:33 +0000 (UTC) (envelope-from raj@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m1IGQXQZ039929 for ; Mon, 18 Feb 2008 16:26:33 GMT (envelope-from raj@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m1IGQX7s039926 for perforce@freebsd.org; Mon, 18 Feb 2008 16:26:33 GMT (envelope-from raj@freebsd.org) Date: Mon, 18 Feb 2008 16:26:33 GMT Message-Id: <200802181626.m1IGQX7s039926@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to raj@freebsd.org using -f From: Rafal Jaworowski To: Perforce Change Reviews Cc: Subject: PERFORCE change 135658 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Feb 2008 16:26:34 -0000 http://perforce.freebsd.org/chv.cgi?CH=135658 Change 135658 by raj@raj_mimi on 2008/02/18 16:26:01 Extend bootinfo metadata and its handling, so that multiple memory regions and Ethernet addresses are passed to the kernel. Affected files ... .. //depot/projects/e500/sys/boot/powerpc/uboot/metadata.c#6 edit .. //depot/projects/e500/sys/boot/uboot/common/main.c#6 edit .. //depot/projects/e500/sys/powerpc/booke/machdep.c#8 edit .. //depot/projects/e500/sys/powerpc/booke/pmap.c#11 edit .. //depot/projects/e500/sys/powerpc/include/bootinfo.h#4 edit .. //depot/projects/e500/sys/powerpc/include/pmap.h#4 edit .. //depot/projects/e500/sys/powerpc/mpc85xx/ocpbus.c#4 edit Differences ... ==== //depot/projects/e500/sys/boot/powerpc/uboot/metadata.c#6 (text+ko) ==== @@ -1,6 +1,6 @@ /*- * Copyright (c) 1998 Michael Smith - * Copyright (C) 2007 Semihalf, Piotr Kruszynski + * Copyright (C) 2007-2008 Semihalf, Piotr Kruszynski * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,8 +40,10 @@ #include "api_public.h" #include "bootstrap.h" -/* XXX should this go into header? */ +/* XXX this should go into header */ struct sys_info *ub_get_sys_info(void); +const char *ub_env_enum(const char *); +char *ub_env_get(const char *); /* * Return a 'boothowto' value corresponding to the kernel arguments in @@ -66,7 +68,7 @@ {NULL, 0} }; -int +static int md_getboothowto(char *kargs) { char *cp; @@ -142,7 +144,7 @@ * Each variable is formatted as =, with a single nul * separating each variable, and a double nul terminating the environment. */ -vm_offset_t +static vm_offset_t md_copyenv(vm_offset_t addr) { struct env_var *ep; @@ -225,7 +227,7 @@ COPY32(0, a, c); \ } -vm_offset_t +static vm_offset_t md_copymodules(vm_offset_t addr) { struct preloaded_file *fp; @@ -251,6 +253,94 @@ } /* + * Prepare the bootinfo structure. Put a ptr to the allocated struct in addr, + * return size. + */ +static int +md_bootinfo(struct bootinfo **addr) +{ +#define TMP_MAX_ETH 8 +#define TMP_MAX_MR 8 + struct bootinfo *bi; + struct bi_mem_region tmp_mr[TMP_MAX_MR]; + struct bi_eth_addr tmp_eth[TMP_MAX_ETH]; + struct sys_info *si; + char *str, *end; + const char *env; + void *ptr; + u_int8_t tmp_addr[6]; + int i, mr_no, eth_no, size; + + if ((si = ub_get_sys_info()) == NULL) + panic("can't retrieve U-Boot sysinfo"); + + /* + * Handle mem regions (we only care about DRAM) + */ + for (i = 0, mr_no = 0; i < si->mr_no; i++) + if (si->mr[i].flags == MR_ATTR_DRAM) { + if (mr_no >= TMP_MAX_MR) { + printf("too many memory regions: %d\n", + mr_no); + break; + } + tmp_mr[mr_no].mem_base = si->mr[i].start; + tmp_mr[mr_no].mem_size = si->mr[i].size; + mr_no++; + continue; + } + if (mr_no == 0) + panic("can't retrieve RAM info"); + + size = (mr_no * sizeof(struct bi_mem_region) - sizeof(bi->bi_data)); + + /* + * Handle Ethernet addresses: parse u-boot env for eth%daddr + */ + env = NULL; + eth_no = 0; + while ((env = ub_env_enum(env)) != NULL) + if (strncmp(env, "eth", 3) == 0 && + strncmp(env + (strlen(env) - 4), "addr", 4) == 0) { + + str = ub_env_get(env); + for (i = 0; i < 6; i++) { + tmp_addr[i] = str ? strtol(str, &end, 16) : 0; + if (str) + str = (*end) ? end + 1 : end; + + tmp_eth[eth_no].mac_addr[i] = tmp_addr[i]; + } + eth_no++; + } + + size += (eth_no * sizeof(struct bi_eth_addr)) + sizeof(struct bootinfo); + + /* + * Once its whole size is calculated, allocate space for the bootinfo + * and copy over the contents from temp containers. + */ + if ((bi = malloc(size)) == NULL) + panic("can't allocate mem for bootinfo"); + + ptr = (struct bi_mem_region *)bi->bi_data; + bcopy(tmp_mr, ptr, mr_no * sizeof(struct bi_mem_region)); + ptr += mr_no * sizeof(struct bi_mem_region); + bcopy(tmp_eth, ptr, eth_no * sizeof(struct bi_eth_addr)); + + bi->bi_mem_reg_no = mr_no; + bi->bi_eth_addr_no = eth_no; + bi->bi_version = BI_VERSION; + bi->bi_bar_base = si->bar; + bi->bi_cpu_clk = si->clk_cpu; + bi->bi_bus_clk = si->clk_bus; + + *addr = bi; + + return (size); +} + +/* * Load the information expected by a powerpc kernel. * * - The 'boothowto' argument is constructed @@ -261,18 +351,18 @@ int md_load(char *args, vm_offset_t *modulep) { - struct bootinfo bootinfo; struct preloaded_file *kfp; struct preloaded_file *xp; struct file_metadata *md; + struct bootinfo *bip; vm_offset_t kernend; vm_offset_t addr; vm_offset_t envp; vm_offset_t size; vm_offset_t vaddr; - struct sys_info *si; char *rootdevname; int howto; + int bisize; int i; /* This metadata addreses must be converted for kernel after relocation */ @@ -308,31 +398,9 @@ /* pad to a page boundary */ addr = roundup(addr, PAGE_SIZE); - /* Fill information structure */ - if (!(si = ub_get_sys_info())) - panic("can't retrieve U-Boot sysinfo"); + /* prepare bootinfo */ + bisize = md_bootinfo(&bip); - /* Extract mem info */ - for (i = 0; i < si->mr_no; i++) - if (si->mr[i].flags == MR_ATTR_DRAM) { - bootinfo.mem_base = si->mr[i].start; - bootinfo.mem_size = si->mr[i].size; - break; - } - - if (i == si->mr_no) - panic("can't retrieve memory info"); - - bootinfo.version = 1; - bootinfo.bar_base = si->bar; - bootinfo.cpu_clk = si->clk_cpu; - bootinfo.bus_clk = si->clk_bus; - -#if 0 - memcpy(bootinfo.eth0_addr, bd->bi_enetaddr, sizeof(bootinfo.eth0_addr)); - memcpy(bootinfo.eth1_addr, bd->bi_enet1addr, sizeof(bootinfo.eth1_addr)); -#endif - kernend = 0; kfp = file_findfile(NULL, "elf32 kernel"); if (kfp == NULL) @@ -340,7 +408,7 @@ if (kfp == NULL) panic("can't find kernel file"); file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); - file_addmetadata(kfp, MODINFOMD_BOOTINFO, sizeof bootinfo, &bootinfo); + file_addmetadata(kfp, MODINFOMD_BOOTINFO, bisize, bip); file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); ==== //depot/projects/e500/sys/boot/uboot/common/main.c#6 (text+ko) ==== @@ -96,17 +96,19 @@ static uint64_t memsize(int flags) { - int i; - struct sys_info * si; + int i; + struct sys_info *si; + uint64_t size; if ((si = ub_get_sys_info()) == NULL) return 0; - + + size = 0; for (i = 0; i < si->mr_no; i++) if (si->mr[i].flags == flags && si->mr[i].size) - return (si->mr[i].size); + size += (si->mr[i].size); - return 0; + return (size); } int ==== //depot/projects/e500/sys/powerpc/booke/machdep.c#8 (text+ko) ==== @@ -261,7 +261,9 @@ void dump_bootinfo(void) { - int i; + struct bi_mem_region *mr; + struct bi_eth_addr *eth; + int i, j; debugf("bootinfo:\n"); if (bootinfo == NULL) { @@ -269,22 +271,25 @@ return; } - debugf(" version = 0x%08x\n", bootinfo->version); - debugf(" mem_base = 0x%08x\n", bootinfo->mem_base); - debugf(" mem_size = 0x%08x\n", bootinfo->mem_size); - debugf(" ccsrbar = 0x%08x\n", bootinfo->bar_base); - debugf(" cpu_clk = 0x%08x\n", bootinfo->cpu_clk); - debugf(" bus_clk = 0x%08x\n", bootinfo->bus_clk); + debugf(" version = 0x%08x\n", bootinfo->bi_version); + debugf(" ccsrbar = 0x%08x\n", bootinfo->bi_bar_base); + debugf(" cpu_clk = 0x%08x\n", bootinfo->bi_cpu_clk); + debugf(" bus_clk = 0x%08x\n", bootinfo->bi_bus_clk); - debugf(" eth0_addr = "); - for (i = 0; i < 6; i++) - debugf("%02x ", bootinfo->eth0_addr[i]); - debugf("\n"); + debugf(" mem regions:\n"); + mr = (struct bi_mem_region *)bootinfo->bi_data; + for (i = 0; i < bootinfo->bi_mem_reg_no; i++, mr++) + debugf(" #%d, base = 0x%08x, size = 0x%08x\n", i, + mr->mem_base, mr->mem_size); - debugf(" eth1_addr = "); - for (i = 0; i < 6; i++) - debugf("%02x ", bootinfo->eth1_addr[i]); - debugf("\n"); + debugf(" eth addresses:\n"); + eth = (struct bi_eth_addr *)mr; + for (i = 0; i < bootinfo->bi_eth_addr_no; i++, eth++) { + debugf(" #%d, addr = ", i); + for (j = 0; j < 6; j++) + debugf("%02x ", eth->mac_addr[j]); + debugf("\n"); + } } void @@ -306,6 +311,8 @@ struct pcpu *pc; void *kmdp; vm_offset_t end; + struct bi_mem_region *mr; + int i; kmdp = NULL; @@ -341,18 +348,24 @@ while(1); } - availmem_regions[0].mr_start = bootinfo->mem_base; - availmem_regions[0].mr_size = bootinfo->mem_size; - availmem_regions_sz = 1; + /* Initialize memory regions table */ + mr = (struct bi_mem_region *)bootinfo->bi_data; + for (i = 0; i < bootinfo->bi_mem_reg_no; i++, mr++) { + if (i == MEM_REGIONS) + break; + availmem_regions[i].mr_start = mr->mem_base; + availmem_regions[i].mr_size = mr->mem_size; + } + availmem_regions_sz = i; /* Initialize TLB1 handling */ - tlb1_init(bootinfo->bar_base); + tlb1_init(bootinfo->bi_bar_base); /* * Time Base and Decrementer are updated every 8 CCB bus clocks. * HID0[SEL_TBCLK] = 0 */ - decr_config(bootinfo->bus_clk/8); + decr_config(bootinfo->bi_bus_clk/8); /* Init params/tunables that can be overridden by the loader. */ init_param1(); @@ -368,7 +381,7 @@ pc->pc_cpuid = 0; __asm __volatile("mtsprg 0, %0" :: "r"(pc)); - /* Initialize syste mutexes. */ + /* Initialize system mutexes. */ mutex_init(); /* Initialize the console before printing anything. */ ==== //depot/projects/e500/sys/powerpc/booke/pmap.c#11 (text+ko) ==== @@ -84,6 +84,7 @@ #include #include #include +#include #include #include "mmu_if.h" @@ -109,7 +110,6 @@ /* Kernel physical load address. */ extern uint32_t kernload; -#define MEM_REGIONS 8 struct mem_region availmem_regions[MEM_REGIONS]; int availmem_regions_sz; ==== //depot/projects/e500/sys/powerpc/include/bootinfo.h#4 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2006 Semihalf, Marian Balakowicz + * Copyright (C) 2006-2008 Semihalf, Marian Balakowicz * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,15 +29,36 @@ #define _MACHINE_BOOTINFO_H_ #if !defined(LOCORE) -/* Kernel hardware spec, received from loader(8) */ -struct bootinfo { - u_int32_t version; + +/* Platform hardware spec, received from loader(8) */ + +#define BI_VERSION 1 + +struct bi_mem_region { vm_paddr_t mem_base; vm_size_t mem_size; - vm_offset_t bar_base; - u_int32_t cpu_clk; - u_int32_t bus_clk; - u_int8_t eth0_addr[6]; +}; + +struct bi_eth_addr { + u_int8_t mac_addr[6]; +}; + +struct bootinfo { + u_int32_t bi_version; + vm_offset_t bi_bar_base; + u_int32_t bi_cpu_clk; + u_int32_t bi_bus_clk; + u_int8_t bi_mem_reg_no; + u_int8_t bi_eth_addr_no; + + u_int8_t bi_data[1]; + /* + * The bi_data container is allocated in run time and has the + * following layout: + * + * - bi_mem_reg_no elements of struct bi_mem_region + * - bi_eth_addr_no elements of struct bi_eth_addr + */ }; extern struct bootinfo *bootinfo; ==== //depot/projects/e500/sys/powerpc/include/pmap.h#4 (text+ko) ==== @@ -130,6 +130,7 @@ TAILQ_HEAD(, pv_entry) pv_list; }; +#define MEM_REGIONS 8 #define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list)) #endif /* AIM */ ==== //depot/projects/e500/sys/powerpc/mpc85xx/ocpbus.c#4 (text+ko) ==== @@ -525,7 +525,7 @@ switch (index) { case OCPBUS_IVAR_CLOCK: - *result = bootinfo->bus_clk; + *result = bootinfo->bi_bus_clk; return (0); case OCPBUS_IVAR_DEVTYPE: *result = dinfo->ocp_devtype;