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