diff --git a/Targets/LS2K/dev/load_dtb.c b/Targets/LS2K/dev/load_dtb.c index 63785425..b49e1ff2 100644 --- a/Targets/LS2K/dev/load_dtb.c +++ b/Targets/LS2K/dev/load_dtb.c @@ -1,5 +1,13 @@ #include "target/load_dtb.h" #include +#include +#include +#include +#ifdef PCI_PROBE_ONLY +int pci_probe_only = 2; /*0:nothing, 1:dtb pci use pmon allcated, kernel pci probe only, 2: dtb pci use pmon allocated,kernel pci reassigned.*/ +#else +int pci_probe_only = 0; +#endif int dtb_cksum(void *p, size_t s, int set) { @@ -56,7 +64,130 @@ static int check_mac_ok(void) return 1; } -static int check_dma_ok(void) + +static int check_pci_bridge_ok(void) +{ + const void *nodep; /* property node pointer */ + int nodeoffset; /* node offset from libfdt */ + int len, id, i; /* length of the property */ + char *ethernet_name[]={"/soc/pcie0_port0@40100000", "/soc/pcie0_port1@50000000", "/soc/pcie0_port2@54000000", "/soc/pcie0_port3@58000000", "/soc/pcie1_port0@60000000", "/soc/pcie1_port1@78000000"}; + pcitag_t tag; + unsigned int val, val1, d, start, end; + int dev; + unsigned int data[12]; + + if (!pci_probe_only) return 1; + + for(id = 0, dev=9;id < sizeof(ethernet_name)/sizeof(ethernet_name[0]);id++,dev++) { + nodeoffset = fdt_path_offset (working_fdt, ethernet_name[id]); + if (nodeoffset < 0) { + return 1; //no ethernet device, do nothing + } + nodep = fdt_getprop (working_fdt, nodeoffset, (const char* )"ranges", &len); + if(len <= 0) { + return 1; //no mac prop in ethernet, do nothing + } + + memcpy(data, nodep, 12*4); + + /*pci foarmat(name/len) is flag/1 pciaddr/2 cpuaddr/1 len/2*/ + tag = _pci_make_tag(0, dev, 0); + val = _pci_conf_read32(dev, 0x00); + if ( val != 0xffffffff){ + val =_pci_conf_read32(tag, 0x20); + start = (val & 0xfff0) << 16; + end = val & 0xfff00000; + d = cpu_to_be32(start); + if(data[2] != data[3] || data[2] != d) + return 0; + d = cpu_to_be32(end - start + 0x100000); + if(data[5] != d) + return 0; + val =_pci_conf_read32(tag, 0x30); + val1 =_pci_conf_read32(tag, 0x1c); + start = ((val&0xffff)<<16)+((val1&0xf0)<<8) + 0x18000000; + end = (val&0xffff0000)+(val1&0xf000) + 0x18000000; + d = cpu_to_be32(start); + if(data[6+3] != data[6+2] || data[6+2] != d) + return 0; + d = cpu_to_be32(end - start + 0x1000); + if(data[6+5] != d) + return 0; + } + else + { + if(data[5] != 0 || data[6+5] != 0) + return 0; + } + } + return 1; +} + +static int update_pci_bridge(void * ssp) +{ + const void *nodep; /* property node pointer */ + int nodeoffset; /* node offset from libfdt */ + int len, id, i; /* length of the property */ + u8 mac_addr[6] = {0x00, 0x55, 0x7B, 0xB5, 0x7D, 0xF7}; //default mac address + char *ethernet_name[]={"/soc/pcie0_port0@40100000", "/soc/pcie0_port1@50000000", "/soc/pcie0_port2@54000000", "/soc/pcie0_port3@58000000", "/soc/pcie1_port0@60000000", "/soc/pcie1_port1@78000000"}; + pcitag_t tag; + unsigned int val, val1, start, end; + int dev; + unsigned int data[12]; + unsigned nmem=0x18000000, nio=0x1a000000; + + if (!pci_probe_only) return 0; + + for (id = 0, dev=9;id < sizeof(ethernet_name)/sizeof(ethernet_name[0]);id++,dev++) { + nodeoffset = fdt_path_offset (ssp, ethernet_name[id]); + if (nodeoffset < 0) { + return 1; //no ethernet device, do nothing + } + nodep = fdt_getprop (ssp, nodeoffset, (const char* )"ranges", &len); + if(len <= 0) { + return 1; //no mac prop in ethernet, do nothing + } + + memcpy(data, nodep, 12*4); + + /*pci foarmat(name/len) is flag/1 pciaddr/2 cpuaddr/1 len/2*/ + tag = _pci_make_tag(0, dev, 0); + + val = _pci_conf_read32(tag, 0x00); + if ( val != 0xffffffff){ + val =_pci_conf_read32(tag, 0x20); + start = (val & 0xfff0) << 16; + end = val & 0xfff00000; + data[3] = data[2] = cpu_to_be32(start); + data[5] = cpu_to_be32(end - start + 0x100000); + val =_pci_conf_read32(tag, 0x30); + val1 =_pci_conf_read32(tag, 0x1c); + start = ((val&0xffff)<<16)+((val1&0xf0)<<8) + 0x18000000; + end = (val&0xffff0000)+(val1&0xf000) + 0x18000000; + data[6+3] = data[6+2] = cpu_to_be32(start); + data[6+5] = cpu_to_be32(end - start + 0x1000); + } + else + { + nmem -= 0x100000; + nio -= 0x1000; + data[3] = data[2] = cpu_to_be32(nmem); + data[5] = cpu_to_be32(0x100000); + data[6+3] = data[6+2] = cpu_to_be32(nio); + data[6+5] = cpu_to_be32(0x1000); + } + + if (fdt_setprop(ssp, nodeoffset, "ranges", data, 12*4)) + { + printf("set ranges error\n"); + } + + } + return 0; +} + + +static int check_prop_ok(char *propname, int wanted) { int nodeoffset, len; const void *nodep; /* property node pointer */ @@ -68,9 +199,9 @@ static int check_dma_ok(void) */ return 1; //do nothing } - nodep = fdt_getprop (working_fdt, nodeoffset, "dma-coherent", &len); + nodep = fdt_getprop (working_fdt, nodeoffset, propname, &len); - if(ls2k_version()) { + if(wanted) { if(!nodep) return 0; //should be reset } else @@ -107,7 +238,7 @@ static int update_mac(void * ssp, int id) return 0; } -static int update_dma_flag(void * ssp) +static int update_prop_flag(void * ssp, char *propname, int wanted) { int nodeoffset, len; const void *nodep; /* property node pointer */ @@ -120,21 +251,21 @@ static int update_dma_flag(void * ssp) printf ("libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); return 1; } - nodep = fdt_getprop (ssp, nodeoffset, "dma-coherent", &len); + nodep = fdt_getprop (ssp, nodeoffset, propname, &len); - if(ls2k_version()) { + if(wanted) { if(!nodep) { - if(fdt_setprop(ssp, nodeoffset, "dma-coherent", NULL, 0)) - printf("Add property \"dma-coherent\" error\n"); + if(fdt_setprop(ssp, nodeoffset, propname, NULL, 0)) + printf("Add property \"%s\" error\n", propname); else - printf("Add property \"dma-coherent\"\n"); + printf("Add property \"%s\"\n", propname); } } else { if(nodep) { - if(fdt_delprop(ssp, nodeoffset, "dma-coherent")) - printf("Delete property \"dma-coherent\" error\n"); + if(fdt_delprop(ssp, nodeoffset, propname)) + printf("Delete property \"%s\" error\n", propname); else - printf("Delete property \"dma-coherent\"\n"); + printf("Delete property \"%s\"\n", propname); } } return 0; @@ -155,12 +286,14 @@ void verify_dtb(void) return; } printf("dtb verify ok!!!\n"); - if(!check_mac_ok() || !check_dma_ok()) { + if(!check_mac_ok() || !check_prop_ok("dma-coherent", ls2k_version()) || !check_prop_ok("pci-probe-only", pci_probe_only == 1) || !check_pci_bridge_ok()) { u8 buff[DTB_SIZE] = {0}; fdt_open_into(working_fdt, buff + 4, DTB_SIZE - 8); - update_dma_flag(buff + 4); + update_prop_flag(buff + 4, "dma-coherent", ls2k_version()); + update_prop_flag(buff + 4, "pci-probe-only", pci_probe_only == 1); update_mac(buff + 4, 0); update_mac(buff + 4, 1); + update_pci_bridge(buff + 4); dtb_cksum(buff, DTB_SIZE - 4, 1); tgt_flashprogram((char *)working_fdt - 4, DTB_SIZE, buff, 0); } @@ -507,7 +640,8 @@ int load_dtb(int argc,char **argv) printf("dtb has a bad bad magic, please reload dtb file!!!\n"); return 0; } - update_dma_flag(heaptop + 4); + update_prop_flag(heaptop + 4, "dma-coherent", ls2k_version()); + update_prop_flag(heaptop + 4, "pci-probe-only", pci_probe_only); update_mac(heaptop + 4, 0); update_mac(heaptop + 4, 1); dtb_cksum(heaptop, DTB_SIZE - 4, 1); diff --git a/Targets/LS2K/pci/pci_machdep.c b/Targets/LS2K/pci/pci_machdep.c index 220980e8..63aa1434 100644 --- a/Targets/LS2K/pci/pci_machdep.c +++ b/Targets/LS2K/pci/pci_machdep.c @@ -60,6 +60,7 @@ extern int _pciverbose; extern char hwethadr[6]; struct pci_device *_pci_bus[16]; int _max_pci_bus = 0; +extern int pci_probe_only; /* PCI mem regions in PCI space */ @@ -82,9 +83,13 @@ _pci_hwinit(initialise, iot, memt) struct pci_device *pd; struct pci_bus *pb; int newcfg=0; + char *env; SBD_DISPLAY ("HW-0", 0); if(getenv("newcfg"))newcfg=1; + if ((env = getenv("pci_probe_only"))) + pci_probe_only = strtoul(env, 0, 0); + if (!initialise) { return(0); } @@ -117,13 +122,17 @@ _pci_hwinit(initialise, iot, memt) _pci_head = pd; SBD_DISPLAY ("HW-3", 0); -#undef BONITO_PCILO0_BASE -#undef BONITO_PCILO_SIZE; -#define BONITO_PCILO0_BASE 0x10000000 -#define BONITO_PCILO_SIZE 0x08000000 + if(pci_probe_only) + { + pb->minpcimemaddr = 0x40100000; + pb->nextpcimemaddr = 0x80000000; + } + else + { + pb->minpcimemaddr = 0x10000000; + pb->nextpcimemaddr = 0x18000000; + } - pb->minpcimemaddr = BONITO_PCILO0_BASE; // 0x4000_0000 - pb->nextpcimemaddr = BONITO_PCILO0_BASE+BONITO_PCILO_SIZE; // 0x4000_0000 + 0x4000_0000 pb->minpciioaddr = PCI_IO_SPACE_BASE+0x0004000; pb->nextpciioaddr = PCI_IO_SPACE_BASE+ BONITO_PCIIO_SIZE; // 0 + 0x0200_0000 pb->pci_mem_base = BONITO_PCILO_BASE_VA; @@ -321,6 +330,9 @@ pcireg_t pci_alloc_fixmemio(struct pci_win *pm) } else { + if(pci_probe_only) + return -1; + if(reg == PCI_MEMBASE_1) { size = pci_config_array[idx].mem_end - pci_config_array[idx].mem_start + 1;