Power PC VME Memory Accesses Dennis J. Nicklaus March 1999 This note describes what I have learned about VME memory access by mv2300 and mv2600 series Power PCs. All the following addresses are valid only if you have NOT enabled extended VME address space, which is the default. All addresses are given in hex. Files referenced are in /usr/wind_ppc/target/config/mv2303/. From mv2600.h, vxworks maps local address d8000000 (VME_A32_MSTR_LOCAL) to VME address 08000000 (VME_A32_MSTR_BUS, defined in config.h), so if you dump d8000000, you see what on the VME bus responds to 08000000. Also by default, a processor will expose it's local DRAM to the VME Bus. The local memory, which starts at local cpu address 0 (LOCAL_MEM_LOCAL_ADRS from config.h) is made readable via the VME bus at VME address 0x08000000 (VME_A32_SLV_BUS, set = to VME_A32_MSTR_BUS, both in config.h). From the board's PCI bus (which is how VME requests would come in), the local DRAM looks like it is at address 80000000 (PCI2DRAM_BASE_ADRS, from mv2600.h), so to make the DRAM VME readable at 08000000, it maps the addresses 08000000 to 09000000 (the amount of DRAM is 16 MB, as set in config.h by VME_A32_SLV_SIZE which is = to LOCAL_MEM_SIZE) into its own PCI Bus address of 80000000 (PCI2DRAM_BASE_ADRS) (which, again, points to the same place as the local CPU address of 0). The vxworks source file universe.c sets up the registers which expose the local DRAM to the VME bus. BUT the local DRAM is so exposed ONLY if nthe processor number is set to 0 (zero). You set the processor number with the second field of bootChange. The idea is, if you have multiple processors, you set one to processor 0, and it is the one whose DRAM gets mapped onto VME bus addresses 08000000. By default, any other's (any processor with boot processor number (vxworks global variable sysProcNum) not equal to zero) DRAM will not be exposed to the VMEbus. However, in my experiments with exactly 2 processors, it works fine if you set both processor numbers to 0 and both get their local DRAM mapped to the default VME address of d8000000. Dumping address d8000000 from either one shows the DRAM of the other, even though both processors are really putting their DRAM at the same VME address (08000000). I guess that it works because a processor knows the difference between a local address reference and one that it needs to get from elsewhere on the VME bus. If you were to add another processor, then you would have problems unless you change them so they all are exposing DRAM to a different VME address. A few more details: Registers on the universe chip control these address mappings (exposing addresses to the VME bus). The Universe can map 4 separate "images" (or memory blocks) into 4 separate VME addresses. These images are numbered 0-3. Image 1 is the one vxworks uses to map the local DRAM to the VME bus. Each image has four registers: control, address base (start), address bound (finish), and translation offset. The following #defines in universe.h show the addresses of these registers.: UNIVERSE_VSI1_CTL, _BS, _BD, and _TO starting at offset F14 from the UNIVERSE_BASE_ADRS. The file mv2600.h has these #defines CPU_PCI_MEM_ADRS 0xc1000000 VME_DEV_SPACE 0x50000 UNIVERSE_BASE_ADRS ( CPU_PCI_MEM_ADRS + VME_DEV_SPACE ) Using these values from both mv2600.h and universe.h, we see if we dump address c1050f14, those are the registers. Here's the default set up. -> m 0xc1050f14,4 c1050f14: 0000f2a0- c1050f18: 00000008- c1050f1c: 00000009- c1050f20: 00000078- Note also that the PCI registers are little endian, just to throw a little more confusion into the mix. Unswap the address registers and they should look like the values discussed above. Note that the base address + the translation offset gives the PCI2DRAM_BASE_ADRS (08000000+78000000=80000000). The values of the various bits for the control register are defined in the Tundra Universe manual, table A-60, page App A-71. According to how I read the Universe Manual, the Translation offset ought to support the 20 most sig. bits, but in reality, only the top 16 are used. Also note that only the top 16bits for the base and bound addresses are useable. (Meaning the address you "expose" has to start on a 64kb boundary.) If/when I get to this point of 3 processors: I would make the following changes: in file universe.c, function sysUniverseInit2(). 1. take out the "if (procNum == 0)" condition. 2. Change the value of VAL_VSI1_BS (the start address, currently #defined in mv2600.h) to be : VAL_VSI1_BS = VME_A32_SLV_BUS + sysProcNum*VME_A32_SLV_SIZE; Then you have to recompute the end and offset (VAL_VSI1_BD and VAL_VSI1_TO) based on that new starting address also. In this way, processor 0 remains mapped at 08000000, processor 1 at 09000000, processor 2 at 0a000000,... These would be visible from any one processor by looking at its local address d8000000, d9000000, da000000,... Note that you have 128 MB of VME memory space available without going to extended vme. You can modify the universe registers "on-the-fly" while running, if you want to change the mapping, and it takes effect immediately. There is one more bit in a register that has to be set in order for a VMEbus slave image to respond to an incoming cycle. This is in the PCI_CSR (Configuration Space Control and Status Register), which is at offset 004 from the PCI memory start, or at address: c1050004. It is the 3rd bit, or, in big-endian notation, bit 00000004 which must be set so the slave image responds. But since the PCI is little-endian, if you dump that location, it will look like the following bit: 04000000. This bit seems to be set by default by vxworks, so I haven't had to worry about it. See page App-A7 of the Universe User Manual (Kevin Martin has this manual). The End