Module Name: src Committed By: skrll Date: Sun Oct 14 16:16:52 UTC 2012
Modified Files: src/sys/arch/evbarm/rpi: rpi_machdep.c Added Files: src/sys/arch/evbarm/rpi: vcio.h vcprop.h Log Message: Add the Raspberry PI firmware VC mailbox channel numbers. Add some VC property tag definitions and use them to get ARM/VC memory split. Grab a few others things in the process, but don't do anything other than display them when VERBOSE_INIT_ARM is defined. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/sys/arch/evbarm/rpi/rpi_machdep.c cvs rdiff -u -r0 -r1.1 src/sys/arch/evbarm/rpi/vcio.h \ src/sys/arch/evbarm/rpi/vcprop.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/evbarm/rpi/rpi_machdep.c diff -u src/sys/arch/evbarm/rpi/rpi_machdep.c:1.12 src/sys/arch/evbarm/rpi/rpi_machdep.c:1.13 --- src/sys/arch/evbarm/rpi/rpi_machdep.c:1.12 Sat Oct 13 14:22:12 2012 +++ src/sys/arch/evbarm/rpi/rpi_machdep.c Sun Oct 14 16:16:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: rpi_machdep.c,v 1.12 2012/10/13 14:22:12 skrll Exp $ */ +/* $NetBSD: rpi_machdep.c,v 1.13 2012/10/14 16:16:52 skrll Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.12 2012/10/13 14:22:12 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.13 2012/10/14 16:16:52 skrll Exp $"); #include "opt_evbarm_boardtype.h" @@ -49,8 +49,13 @@ __KERNEL_RCSID(0, "$NetBSD: rpi_machdep. #include <machine/bootconfig.h> #include <machine/pmap.h> +#include <arm/broadcom/bcm2835reg.h> #include <arm/broadcom/bcm2835var.h> #include <arm/broadcom/bcm2835_pmvar.h> +#include <arm/broadcom/bcm2835_mbox.h> + +#include <evbarm/rpi/vcio.h> +#include <evbarm/rpi/vcprop.h> #include <evbarm/rpi/rpi.h> @@ -66,11 +71,16 @@ BootConfig bootconfig; /* Boot config s static char bootargs[MAX_BOOT_STRING]; char *boot_args = NULL; +void rpi_bootparams(void); + /* * Macros to translate between physical and virtual for a subset of the * kernel address space. *Not* for general use. */ -#define KERNEL_BASE_PHYS (paddr_t)0 +#define KERNEL_BASE_PHYS (paddr_t)0 + +#define KERN_VTOPHYS(va) \ + ((paddr_t)((vaddr_t)va - KERNEL_BASE + KERNEL_BASE_PHYS)) #define KERN_PHYSTOV(pa) \ ((vaddr_t)((paddr_t)pa - KERNEL_BASE_PHYS + KERNEL_BASE)) @@ -103,7 +113,137 @@ int plcomcnmode = PLCONMODE; #endif /* Smallest amount of RAM start.elf could give us. */ -#define RPI_MINIMUM_ARM_RAM_SPLIT (128U * 1024 * 1024) +#define RPI_MINIMUM_SPLIT (128U * 1024 * 1024) + +static struct { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_fwrev vbt_fwrev; + struct vcprop_tag_boardmodel vbt_boardmodel; + struct vcprop_tag_boardrev vbt_boardrev; + struct vcprop_tag_macaddr vbt_macaddr; + struct vcprop_tag_memory vbt_memory; + struct vcprop_tag_boardserial vbt_serial; + struct vcprop_tag_cmdline vbt_cmdline; + struct vcprop_tag end; +} vb __packed __aligned(16) = +{ + .vb_hdr = { + .vpb_len = sizeof(vb), + .vpb_rcode = VCPROP_PROCESS_REQUEST, + }, + .vbt_fwrev = { + .tag = { + .vpt_tag = VCPROPTAG_GET_FIRMWAREREV, + .vpt_len = VCPROPTAG_LEN(vb.vbt_fwrev), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_boardmodel = { + .tag = { + .vpt_tag = VCPROPTAG_GET_BOARDMODEL, + .vpt_len = VCPROPTAG_LEN(vb.vbt_boardmodel), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_boardrev = { + .tag = { + .vpt_tag = VCPROPTAG_GET_BOARDREVISION, + .vpt_len = VCPROPTAG_LEN(vb.vbt_boardrev), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_macaddr = { + .tag = { + .vpt_tag = VCPROPTAG_GET_MACADDRESS, + .vpt_len = VCPROPTAG_LEN(vb.vbt_macaddr), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_memory = { + .tag = { + .vpt_tag = VCPROPTAG_GET_ARMMEMORY, + .vpt_len = VCPROPTAG_LEN(vb.vbt_memory), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_serial = { + .tag = { + .vpt_tag = VCPROPTAG_GET_BOARDSERIAL, + .vpt_len = VCPROPTAG_LEN(vb.vbt_serial), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_cmdline = { + .tag = { + .vpt_tag = VCPROPTAG_GET_CMDLINE, + .vpt_len = VCPROPTAG_LEN(vb.vbt_cmdline), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .end = { + .vpt_tag = VCPROPTAG_NULL + } +}; + +void +rpi_bootparams(void) +{ + bus_space_tag_t iot = &bcm2835_bs_tag; + bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(BCM2835_ARMMBOX_BASE); + uint32_t res; + + bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANARM2VC, KERN_VTOPHYS(&vb)); + + bcm2835_mbox_read(iot, ioh, BCMMBOX_CHANARM2VC, &res); + + /* + * No need to invalid the cache as the memory has never been referenced + * by the ARM. + * + * cpu_dcache_inv_range((vaddr_t)&vb, sizeof(vb)); + * + */ + + if (!vcprop_buffer_success_p(&vb.vb_hdr)) { + bootconfig.dramblocks = 1; + bootconfig.dram[0].address = 0x0; + bootconfig.dram[0].pages = atop(RPI_MINIMUM_SPLIT); + return; + } + + struct vcprop_tag_memory *vptp_mem = &vb.vbt_memory; + + if (vcprop_tag_success_p(&vptp_mem->tag)) { + size_t n = vcprop_tag_resplen(&vptp_mem->tag) / + sizeof(struct vcprop_memory); + + for (int i = 0; i < n && i < DRAM_BLOCKS; i++) { + bootconfig.dram[i].address = vptp_mem->mem[i].base; + bootconfig.dram[i].pages = atop(vptp_mem->mem[i].size); + } + } + +#ifdef VERBOSE_INIT_ARM + if (vcprop_tag_success_p(&vb.vbt_fwrev.tag)) + printf("%s: firmware rev %x\n", __func__, + vb.vbt_fwrev.rev); + if (vcprop_tag_success_p(&vb.vbt_macaddr.tag)) + printf("%s: mac-address %llx\n", __func__, + vb.vbt_macaddr.addr); + if (vcprop_tag_success_p(&vb.vbt_boardmodel.tag)) + printf("%s: board model %x\n", __func__, + vb.vbt_boardmodel.model); + if (vcprop_tag_success_p(&vb.vbt_boardrev.tag)) + printf("%s: board rev %x\n", __func__, + vb.vbt_boardrev.rev); + if (vcprop_tag_success_p(&vb.vbt_serial.tag)) + printf("%s: board serial %llx\n", __func__, + vb.vbt_serial.sn); + if (vcprop_tag_success_p(&vb.vbt_cmdline.tag)) + printf("%s: cmdline %s\n", __func__, + vb.vbt_cmdline.cmdline); +#endif +} /* * Static device mappings. These peripheral registers are mapped at @@ -137,63 +277,6 @@ static const struct pmap_devmap rpi_devm #undef _A #undef _S -#define LINUX_ARM_MACHTYPE_BCM2708 3138 - -#define LINUX_ATAG_NONE 0x00000000 -struct linux_atag_header { - uint32_t size; - uint32_t tag; -} __packed __aligned(4); - -#define LINUX_ATAG_MEM 0x54410002 -struct linux_atag_mem { - uint32_t size; - uint32_t start; -} __packed __aligned(4); - -#define LINUX_ATAG_CMDLINE 0x54410009 -struct linux_atag_cmdline { - char cmdline[1]; -} __packed __aligned(4); - -struct linux_atag { - struct linux_atag_header hdr; - union { - struct linux_atag_mem mem; - struct linux_atag_cmdline cmdline; - } u; -} __packed __aligned(4); - -static void -parse_linux_atags(void *atag_base) -{ - struct linux_atag *atp; - - for (atp = atag_base; - atp->hdr.size >= sizeof(struct linux_atag_header)/sizeof(uint32_t); - atp = (void *)((uintptr_t)atp + sizeof(uint32_t) * atp->hdr.size)) { - printf("atag: size %08x tag %08x\n", atp->hdr.size, atp->hdr.tag); - if (atp->hdr.tag == LINUX_ATAG_MEM) { - if (bootconfig.dramblocks > 1) { - printf("Ignoring RAM block 0x%08x-0x%08x\n", - atp->u.mem.start, atp->u.mem.start + - atp->u.mem.size - 1); - continue; - } - KASSERT(atp->u.mem.start == 0); - bootconfig.dram[bootconfig.dramblocks].address = 0x0; - bootconfig.dram[bootconfig.dramblocks].pages = - atp->u.mem.size / PAGE_SIZE; - ++bootconfig.dramblocks; - } - - if (atp->hdr.tag == LINUX_ATAG_CMDLINE) { - strncpy(bootargs, atp->u.cmdline.cmdline, - sizeof(bootargs)); - } - } -} - /* * u_int initarm(...) * @@ -229,25 +312,14 @@ initarm(void *arg) #define _BDSTR(s) #s printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n"); - bootargs[0] = '\0'; + rpi_bootparams(); #ifdef VERBOSE_INIT_ARM printf("initarm: Configuring system ...\n"); #endif - - extern const uint32_t rpi_boot_regs[4]; - if (rpi_boot_regs[0] == 0 && - rpi_boot_regs[1] == LINUX_ARM_MACHTYPE_BCM2708) { - parse_linux_atags((void *)KERN_PHYSTOV(rpi_boot_regs[2])); - } else { - bootconfig.dramblocks = 1; - - bootconfig.dram[0].address = 0x0; - bootconfig.dram[0].pages = - RPI_MINIMUM_ARM_RAM_SPLIT / PAGE_SIZE; - } arm32_bootmem_init(bootconfig.dram[0].address, bootconfig.dram[0].pages * PAGE_SIZE, bootconfig.dram[0].address); + arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_HIGH, 0, rpi_devmap, false); Added files: Index: src/sys/arch/evbarm/rpi/vcio.h diff -u /dev/null src/sys/arch/evbarm/rpi/vcio.h:1.1 --- /dev/null Sun Oct 14 16:16:52 2012 +++ src/sys/arch/evbarm/rpi/vcio.h Sun Oct 14 16:16:52 2012 @@ -0,0 +1,45 @@ +/* $NetBSD: vcio.h,v 1.1 2012/10/14 16:16:52 skrll Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _EVBARM_RPI_VCIO_H_ +#define _EVBARM_RPI_VCIO_H_ + +#define BCMMBOX_CHANPM 0 +#define BCMMBOX_CHANFB 1 /* will be depreciated */ +#define BCMMBOX_CHANVUART 2 +#define BCMMBOX_CHANVCHIQ 3 +#define BCMMBOX_CHANLEDS 4 +#define BCMMBOX_CHANBUTTONS 5 +#define BCMMBOX_CHANTOUCHSCR 6 +#define BCMMBOX_CHANARM2VC 8 +#define BCMMBOX_CHANVC2ARM 9 + +#endif /* _EVBARM_RPI_VCIO_H_ */ Index: src/sys/arch/evbarm/rpi/vcprop.h diff -u /dev/null src/sys/arch/evbarm/rpi/vcprop.h:1.1 --- /dev/null Sun Oct 14 16:16:52 2012 +++ src/sys/arch/evbarm/rpi/vcprop.h Sun Oct 14 16:16:52 2012 @@ -0,0 +1,149 @@ +/* $NetBSD: vcprop.h,v 1.1 2012/10/14 16:16:52 skrll Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Mailbox property interface + */ + +#ifndef _EVBARM_RPI_VCPROP_H_ +#define _EVBARM_RPI_VCPROP_H_ + +struct vcprop_tag { + uint32_t vpt_tag; +#define VCPROPTAG_NULL 0x00000000 +#define VCPROPTAG_GET_FIRMWAREREV 0x00000001 +#define VCPROPTAG_GET_BOARDMODEL 0x00010001 +#define VCPROPTAG_GET_BOARDREVISION 0x00010002 +#define VCPROPTAG_GET_MACADDRESS 0x00010003 +#define VCPROPTAG_GET_BOARDSERIAL 0x00010004 +#define VCPROPTAG_GET_ARMMEMORY 0x00010005 +#define VCPROPTAG_GET_VCMEMORY 0x00010006 +#define VCPROPTAG_GET_CLOCKS 0x00010007 + +#define VCPROPTAG_GET_CMDLINE 0x00050001 +#define VCPROPTAG_GET_DMACHAN 0x00060001 + uint32_t vpt_len; + uint32_t vpt_rcode; +#define VCPROPTAG_REQUEST (0U << 31) +#define VCPROPTAG_RESPONSE (1U << 31) + +}; + +#define VCPROPTAG_LEN(x) (sizeof((x)) - sizeof(struct vcprop_tag)) + +struct vcprop_memory { + uint32_t base; + uint32_t size; +}; + +#define VCPROP_MAXMEMBLOCKS 4 +struct vcprop_tag_memory { + struct vcprop_tag tag; + struct vcprop_memory mem[VCPROP_MAXMEMBLOCKS]; +}; + +struct vcprop_tag_fwrev { + struct vcprop_tag tag; + uint32_t rev; +}; + +struct vcprop_tag_boardmodel { + struct vcprop_tag tag; + uint32_t model; +} ; + +struct vcprop_tag_boardrev { + struct vcprop_tag tag; + uint32_t rev; +} ; + +struct vcprop_tag_macaddr { + struct vcprop_tag tag; + uint64_t addr; +}; + +struct vcprop_tag_boardserial { + struct vcprop_tag tag; + uint64_t sn; +}; + +struct vcprop_clock { + uint32_t pclk; + uint32_t cclk; +}; + +#define VCPROP_MAXCLOCKS 16 +struct vcprop_tag_clock { + struct vcprop_tag tag; + struct vcprop_clock clk[VCPROP_MAXCLOCKS]; +}; + +#define VCPROP_MAXCMDLINE 256 +struct vcprop_tag_cmdline { + struct vcprop_tag tag; + uint8_t cmdline[VCPROP_MAXCMDLINE]; +}; + +struct vcprop_tag_dmachan { + struct vcprop_tag tag; + uint32_t mask; +}; + +struct vcprop_buffer_hdr { + uint32_t vpb_len; + uint32_t vpb_rcode; +#define VCPROP_PROCESS_REQUEST 0 +#define VCPROP_REQ_SUCCESS (1U << 31) +#define VCPROP_REQ_EPARSE (1U << 0) +}; + +static inline bool +vcprop_buffer_success_p(struct vcprop_buffer_hdr *vpbh) +{ + + return (vpbh->vpb_rcode & VCPROP_REQ_SUCCESS); +} + +static inline bool +vcprop_tag_success_p(struct vcprop_tag *vpbt) +{ + + return (vpbt->vpt_rcode & VCPROPTAG_RESPONSE); +} + +static inline size_t +vcprop_tag_resplen(struct vcprop_tag *vpbt) +{ + + return (vpbt->vpt_rcode & ~VCPROPTAG_RESPONSE); +} + +#endif /* _EVBARM_RPI_VCPROP_H_ */