diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2013-11-17 02:03:36 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2013-11-17 02:03:36 +0000 |
commit | a56d243099af85c4da626239a7c3e4e4d4213f53 (patch) | |
tree | 2bab822133b461d9a8600e683d63bcd6b716e341 /sys/powerpc/mpc85xx | |
parent | 3e8a8500643d06119321364ef03de9885ea5d489 (diff) | |
download | FreeBSD-src-a56d243099af85c4da626239a7c3e4e4d4213f53.zip FreeBSD-src-a56d243099af85c4da626239a7c3e4e4d4213f53.tar.gz |
Move CCSR discovery into the platform module, while simultaneously making
it more flexible about how the CCSR range is found. With this change, the
stock MPC85XX will boot on a Routerboard 800.
Hardware donated by: Benjamin Perrault
Diffstat (limited to 'sys/powerpc/mpc85xx')
-rw-r--r-- | sys/powerpc/mpc85xx/mpc85xx.h | 3 | ||||
-rw-r--r-- | sys/powerpc/mpc85xx/platform_mpc85xx.c | 55 |
2 files changed, 56 insertions, 2 deletions
diff --git a/sys/powerpc/mpc85xx/mpc85xx.h b/sys/powerpc/mpc85xx/mpc85xx.h index defb3bf..c3cbf55 100644 --- a/sys/powerpc/mpc85xx/mpc85xx.h +++ b/sys/powerpc/mpc85xx/mpc85xx.h @@ -33,7 +33,8 @@ /* * Configuration control and status registers */ -#define CCSRBAR_VA fdt_immr_va +extern vm_offset_t ccsrbar_va; +#define CCSRBAR_VA ccsrbar_va #define OCP85XX_CCSRBAR (CCSRBAR_VA + 0x0) #define OCP85XX_BPTR (CCSRBAR_VA + 0x20) diff --git a/sys/powerpc/mpc85xx/platform_mpc85xx.c b/sys/powerpc/mpc85xx/platform_mpc85xx.c index b98e031..b190392 100644 --- a/sys/powerpc/mpc85xx/platform_mpc85xx.c +++ b/sys/powerpc/mpc85xx/platform_mpc85xx.c @@ -49,6 +49,9 @@ __FBSDID("$FreeBSD$"); #include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/openfirm.h> +#include <vm/vm.h> +#include <vm/pmap.h> + #include <powerpc/mpc85xx/mpc85xx.h> #include "platform_if.h" @@ -63,6 +66,7 @@ extern uint32_t bp_tlb1_end[]; #endif extern uint32_t *bootinfo; +vm_offset_t ccsrbar_va; static int cpu, maxcpu; @@ -116,8 +120,12 @@ mpc85xx_probe(platform_t plat) static int mpc85xx_attach(platform_t plat) { - phandle_t cpus, child; + phandle_t cpus, child, ccsr; + const char *soc_name_guesses[] = {"/soc", "soc", NULL}; + const char **name; + pcell_t ranges[6], acells, pacells, scells; uint32_t sr; + uint64_t ccsrbar, ccsrsize; int i, law_max, tgt; if ((cpus = OF_finddevice("/cpus")) != -1) { @@ -128,6 +136,51 @@ mpc85xx_attach(platform_t plat) maxcpu = 1; /* + * Locate CCSR region. Irritatingly, there is no way to find it + * unless you already know where it is. Try to infer its location + * from the device tree. + */ + + ccsr = -1; + for (name = soc_name_guesses; *name != NULL && ccsr == -1; name++) + ccsr = OF_finddevice(*name); + if (ccsr == -1) { + char type[64]; + + /* That didn't work. Search for devices of type "soc" */ + child = OF_child(OF_peer(0)); + for (OF_child(child); child != 0; child = OF_peer(child)) { + if (OF_getprop(child, "device_type", type, sizeof(type)) + <= 0) + continue; + + if (strcmp(type, "soc") == 0) { + ccsr = child; + break; + } + } + } + + if (ccsr == -1) + panic("Could not locate CCSR window!"); + + OF_getprop(ccsr, "#size-cells", &scells, sizeof(scells)); + OF_getprop(ccsr, "#address-cells", &acells, sizeof(acells)); + OF_searchprop(OF_parent(ccsr), "#address-cells", &pacells, + sizeof(pacells)); + OF_getprop(ccsr, "ranges", ranges, sizeof(ranges)); + ccsrbar = ccsrsize = 0; + for (i = acells; i < acells + pacells; i++) { + ccsrbar <<= 32; + ccsrbar |= ranges[i]; + } + for (i = acells + pacells; i < acells + pacells + scells; i++) { + ccsrsize <<= 32; + ccsrsize |= ranges[i]; + } + ccsrbar_va = pmap_early_io_map(ccsrbar, ccsrsize); + + /* * Clear local access windows. Skip DRAM entries, so we don't shoot * ourselves in the foot. */ |