PERFORCE change 135658 for review

Rafal Jaworowski raj at FreeBSD.org
Mon Feb 18 08:26:34 PST 2008


http://perforce.freebsd.org/chv.cgi?CH=135658

Change 135658 by raj at 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 <msmith at freebsd.org>
- * Copyright (C) 2007 Semihalf, Piotr Kruszynski <ppk at semihalf.com>
+ * Copyright (C) 2007-2008 Semihalf, Piotr Kruszynski <ppk at semihalf.com>
  * 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 <name>=<value>, 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 <machine/vmparam.h>
 #include <machine/md_var.h>
 #include <machine/mmuvar.h>
+#include <machine/pmap.h>
 #include <machine/pte.h>
 
 #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 <m8 at semihalf.com>
+ * Copyright (C) 2006-2008 Semihalf, Marian Balakowicz <m8 at semihalf.com>
  * 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;


More information about the p4-projects mailing list