Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:04

0001 /**
0002  * @file
0003  *
0004  * @ingroup arm_start
0005  *
0006  * @brief Raspberry pi startup code.
0007  */
0008 
0009 /*
0010  * Copyright (c) 2013 by Alan Cudmore
0011  *
0012  *  The license and distribution terms for this file may be
0013  *  found in the file LICENSE in this distribution or at
0014  *
0015  *  http://www.rtems.org/license/LICENSE
0016  */
0017 
0018 #include <bsp.h>
0019 #include <bsp/bootcard.h>
0020 #include <bsp/irq-generic.h>
0021 #include <bsp/irq.h>
0022 #include <bsp/linker-symbols.h>
0023 #include <bsp/stackalloc.h>
0024 #include <bsp/raspberrypi.h>
0025 #include <bsp/vc.h>
0026 #include <bsp/fdt.h>
0027 
0028 #include <libfdt.h>
0029 
0030 static const struct {
0031     uint32_t code;
0032     const char* label;
0033 } rpi_codes[] =
0034 {
0035     { 0x900021, "A+ 1.1 (512MB)" },
0036     { 0x900032, "B+ 1.2 (512MB)" },
0037     { 0x900092, "Zero 1.2 (512MB)" },
0038     { 0x900093, "Zero 1.3 (512MB)" },
0039     { 0x9000c1, "Zero W 1.1 (512MB)" },
0040     { 0x9020e0, "3A+ 1.0 (512MB)" },
0041     { 0x920092, "Zero 1.2 (512MB)" },
0042     { 0x920093, "Zero 1.3 (512MB)" },
0043     { 0x900061, "CM 1.1 (512MB)" },
0044     { 0xa01040, "2B 1.0 (1GB)" },
0045     { 0xa01041, "2B 1.1 (1GB)" },
0046     { 0xa02082, "3B 1.2 (1GB)" },
0047     { 0xa020a0, "CM3 1.0 (1GB)" },
0048     { 0xa020d3, "3B+ 1.3 (1GB)" },
0049     { 0xa21041, "2B 1.1 (1GB)" },
0050     { 0xa22042, "2B 1,2 (with BCM2837) (1GB)" },
0051     { 0xa22082, "3B 1.2 (1GB)" },
0052     { 0xa220a0, "CM3 1.0 (1GB)" },
0053     { 0xa32082, "3B 1.2 (1GB)" },
0054     { 0xa52082, "3B 1.2 (1GB)" },
0055     { 0xa22083, "3B 1.3 (1GB)" },
0056     { 0xa02100, "CM3+ 1.0 (1GB)" },
0057     { 0xa03111, "4B 1.1 (1GB)" },
0058     { 0xb03111, "4B 1.1 (2GB)" },
0059     { 0xc03111, "4B 1.1 (4GB)" },
0060 };
0061 
0062 static const char* rpi_types[] = {
0063     "A",
0064     "B",
0065     "A+",
0066     "B+",
0067     "2B",
0068     "Alpha (early prototype)",
0069     "CM1",
0070     "3B",
0071     "Zero",
0072     "CM3",
0073     "Zero W",
0074     "3B+",
0075     "3A+",
0076     "Internal use only",
0077     "CM3+",
0078     "4B",
0079 };
0080 
0081 static const char* rpi_mem[] =
0082 {
0083     "256MB",
0084     "512MB",
0085     "1GB",
0086     "2GB",
0087     "4GB"
0088 };
0089 
0090 #define NUMOF(_s) (sizeof(_s) / sizeof(_s[0]))
0091 
0092 void *raspberrypi_get_reg_of_node(const void *fdt, int node)
0093 {
0094   int len;
0095   const uint32_t *val;
0096 
0097   val = fdt_getprop(fdt, node, "reg", &len);
0098   if (val == NULL || len < 4) {
0099     return NULL;
0100   }
0101 
0102   return (BUS_TO_PHY((void *) fdt32_to_cpu(val[0])));
0103 }
0104 
0105 #ifdef BSP_FDT_IS_SUPPORTED
0106 uint32_t bsp_fdt_map_intr(const uint32_t *intr, size_t icells)
0107 {
0108   uint32_t controller = intr[0];
0109   uint32_t source = intr[1];
0110 
0111   switch ( controller ) {
0112     case 0:
0113         return source + BCM2835_IRQ_ID_BASIC_BASE_ID;
0114         break;
0115     case 1:
0116         return source + BCM2835_IRQ_SET1_MIN;
0117         break;
0118     case 2:
0119         return source + BCM2835_IRQ_SET2_MIN;
0120         break;
0121     default:
0122         return BSP_INTERRUPT_VECTOR_INVALID;
0123         break;
0124   }
0125 }
0126 #endif /* BSP_FDT_IS_SUPPORTED */
0127 
0128 void bsp_start(void)
0129 {
0130     bcm2835_get_board_spec_entries spec = { 0 };
0131 
0132     printk("\nRTEMS RPi ");
0133     if (bcm2835_mailbox_get_board_revision( &spec ) >= 0) {
0134     size_t i;
0135     for (i = 0; i < NUMOF(rpi_codes); ++i) {
0136         if (rpi_codes[i].code == spec.spec) {
0137         printk("%s [%08x]", rpi_codes[i].label, spec.spec);
0138         break;
0139         }
0140     }
0141     if (i >= NUMOF(rpi_codes)) {
0142         uint32_t type = (spec.spec >> 4) & 0xff;
0143         uint32_t mem = (spec.spec >> (4 + 4 + 8 + 4)) & 0xf;
0144         printk(" unknown code [%08x] ", spec.spec);
0145         if (type < NUMOF(rpi_types))
0146         printk(rpi_types[type]);
0147         else
0148         printk("type: %02x", type);
0149         if (mem < NUMOF(rpi_mem))
0150         printk(" %s", rpi_mem[mem]);
0151         else
0152         printk(" mem: %x", mem);
0153     }
0154     printk("\n");
0155     }
0156     else {
0157     printk(": ERROR reading mailbox\n");
0158     }
0159 
0160     bsp_interrupt_initialize();
0161 }