--- zzzz-none-000/linux-3.10.107/arch/mips/bcm47xx/prom.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/mips/bcm47xx/prom.c 2021-02-04 17:41:59.000000000 +0000 @@ -28,102 +28,29 @@ #include #include #include +#include +#include #include #include -#include -#include +#include +#include -static int cfe_cons_handle; +static char bcm47xx_system_type[20] = "Broadcom BCM47XX"; const char *get_system_type(void) { - return "Broadcom BCM47XX"; + return bcm47xx_system_type; } -void prom_putchar(char c) +__init void bcm47xx_set_system_type(u16 chip_id) { - while (cfe_write(cfe_cons_handle, &c, 1) == 0) - ; + snprintf(bcm47xx_system_type, sizeof(bcm47xx_system_type), + (chip_id > 0x9999) ? "Broadcom BCM%d" : + "Broadcom BCM%04X", + chip_id); } -static __init void prom_init_cfe(void) -{ - uint32_t cfe_ept; - uint32_t cfe_handle; - uint32_t cfe_eptseal; - int argc = fw_arg0; - char **envp = (char **) fw_arg2; - int *prom_vec = (int *) fw_arg3; - - /* - * Check if a loader was used; if NOT, the 4 arguments are - * what CFE gives us (handle, 0, EPT and EPTSEAL) - */ - if (argc < 0) { - cfe_handle = (uint32_t)argc; - cfe_ept = (uint32_t)envp; - cfe_eptseal = (uint32_t)prom_vec; - } else { - if ((int)prom_vec < 0) { - /* - * Old loader; all it gives us is the handle, - * so use the "known" entrypoint and assume - * the seal. - */ - cfe_handle = (uint32_t)prom_vec; - cfe_ept = 0xBFC00500; - cfe_eptseal = CFE_EPTSEAL; - } else { - /* - * Newer loaders bundle the handle/ept/eptseal - * Note: prom_vec is in the loader's useg - * which is still alive in the TLB. - */ - cfe_handle = prom_vec[0]; - cfe_ept = prom_vec[2]; - cfe_eptseal = prom_vec[3]; - } - } - - if (cfe_eptseal != CFE_EPTSEAL) { - /* too early for panic to do any good */ - printk(KERN_ERR "CFE's entrypoint seal doesn't match."); - while (1) ; - } - - cfe_init(cfe_handle, cfe_ept); -} - -static __init void prom_init_console(void) -{ - /* Initialize CFE console */ - cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); -} - -static __init void prom_init_cmdline(void) -{ - static char buf[COMMAND_LINE_SIZE] __initdata; - - /* Get the kernel command line from CFE */ - if (cfe_getenv("LINUX_CMDLINE", buf, COMMAND_LINE_SIZE) >= 0) { - buf[COMMAND_LINE_SIZE - 1] = 0; - strcpy(arcs_cmdline, buf); - } - - /* Force a console handover by adding a console= argument if needed, - * as CFE is not available anymore later in the boot process. */ - if ((strstr(arcs_cmdline, "console=")) == NULL) { - /* Try to read the default serial port used by CFE */ - if ((cfe_getenv("BOOT_CONSOLE", buf, COMMAND_LINE_SIZE) < 0) - || (strncmp("uart", buf, 4))) - /* Default to uart0 */ - strcpy(buf, "uart0"); - - /* Compute the new command line */ - snprintf(arcs_cmdline, COMMAND_LINE_SIZE, "%s console=ttyS%c,115200", - arcs_cmdline, buf[4]); - } -} +static unsigned long lowmem __initdata; static __init void prom_init_mem(void) { @@ -143,21 +70,25 @@ * BCM47XX uses 128MB for addressing the ram, if the system contains * less that that amount of ram it remaps the ram more often into the * available space. - * Accessing memory after 128MB will cause an exception. - * max contains the biggest possible address supported by the platform. - * If the method wants to try something above we assume 128MB ram. */ - off = (unsigned long)prom_init; - max = off | ((128 << 20) - 1); - for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { - if ((off + mem) > max) { - mem = (128 << 20); - printk(KERN_DEBUG "assume 128MB RAM\n"); + + /* Physical address, without mapping to any kernel segment */ + off = CPHYSADDR((unsigned long)prom_init); + + /* Accessing memory after 128 MiB will cause an exception */ + max = 128 << 20; + + for (mem = 1 << 20; mem < max; mem += 1 << 20) { + /* Loop condition may be not enough, off may be over 1 MiB */ + if (off + mem >= max) { + mem = max; + pr_debug("Assume 128MB RAM\n"); break; } if (!memcmp(prom_init, prom_init + mem, 32)) break; } + lowmem = mem; /* Ignoring the last page when ddr size is 128M. Cached * accesses to last page is causing the processor to prefetch @@ -166,18 +97,85 @@ */ if (c->cputype == CPU_74K && (mem == (128 << 20))) mem -= 0x1000; - add_memory_region(0, mem, BOOT_MEM_RAM); } +/* + * This is the first serial on the chip common core, it is at this position + * for sb (ssb) and ai (bcma) bus. + */ +#define BCM47XX_SERIAL_ADDR (SSB_ENUM_BASE + SSB_CHIPCO_UART0_DATA) + void __init prom_init(void) { - prom_init_cfe(); - prom_init_console(); - prom_init_cmdline(); prom_init_mem(); + setup_8250_early_printk_port(CKSEG1ADDR(BCM47XX_SERIAL_ADDR), 0, 0); } void __init prom_free_prom_memory(void) { } + +#if defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) + +#define EXTVBASE 0xc0000000 +#define ENTRYLO(x) ((pte_val(pfn_pte((x) >> _PFN_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6) | 1) + +#include + +/* Stripped version of tlb_init, with the call to build_tlb_refill_handler + * dropped. Calling it at this stage causes a hang. + */ +void early_tlb_init(void) +{ + write_c0_pagemask(PM_DEFAULT_MASK); + write_c0_wired(0); + temp_tlb_entry = current_cpu_data.tlbsize - 1; + local_flush_tlb_all(); +} + +void __init bcm47xx_prom_highmem_init(void) +{ + unsigned long off = (unsigned long)prom_init; + unsigned long extmem = 0; + bool highmem_region = false; + + if (WARN_ON(bcm47xx_bus_type != BCM47XX_BUS_TYPE_BCMA)) + return; + + if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706) + highmem_region = true; + + if (lowmem != 128 << 20 || !highmem_region) + return; + + early_tlb_init(); + + /* Add one temporary TLB entry to map SDRAM Region 2. + * Physical Virtual + * 0x80000000 0xc0000000 (1st: 256MB) + * 0x90000000 0xd0000000 (2nd: 256MB) + */ + add_temporary_entry(ENTRYLO(0x80000000), + ENTRYLO(0x80000000 + (256 << 20)), + EXTVBASE, PM_256M); + + off = EXTVBASE + __pa(off); + for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) { + if (!memcmp(prom_init, (void *)(off + extmem), 16)) + break; + } + extmem -= lowmem; + + early_tlb_init(); + + if (!extmem) + return; + + pr_warn("Found %lu MiB of extra memory, but highmem is unsupported yet!\n", + extmem >> 20); + + /* TODO: Register extra memory */ +} + +#endif /* defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) */