System Inspection?
mdavidsaver opened this issue · 8 comments
After the experience of troubleshooting a difficult issue involving MMU configuration, I'm thinking about the practicality of adding some "system inspection" to devlib2. This would probably take the form of IOC shell function(s) to print architecture, OS, or device specific information.
Candidates include:
- Tundra VME bridges, show in/outbound window configuration
- universe 2
- tsi148
- powerpc MMU on RTEMS/vworks
- mvme3100 / MPC8540 / e500v1 - read TLB
- mvme2500 / P2020 / e500v2 - read TLB
- mvme???? / MPC???? - show I/DBATs
Open questions for the MMU part
- To what extent can/should this be an OSI wrapper vs. assembly?
- Are there RTEMS and/or vxworks functions to print some of this information?
- Read from (static) configuration (eg.
sysBatDesc[]
) vs. live inspection?
I have a function that prints the VME windows in vxWorks, but uses the static configuration. Reading the life config would be better, I think. For the IFC1210 board (VME Linux) or better the TOSCA FPGA, which is its VME bus bridge and more, I have something similar. It prints a list of memory maps. For TOSCA, I have fixed A16, A24 and CRCSR (allocated on first use) but A32 may be mapped in multiple smaller chunks, as requested by the user. Thus the number of maps is variable and somewhat dynamic.
This is my vxWorks version (using the static configuration):
STATUS vmeMapShow(void)
{
#if VME_A16_MSTR_SIZE
printf ("VME A16 0x%08x - 0x%08x mapped to 0x%08x - 0x%08x (%d kB)\n",
VME_A16_MSTR_BUS, VME_A16_MSTR_BUS + VME_A16_MSTR_SIZE - 1,
VME_A16_MSTR_LOCAL, VME_A16_MSTR_LOCAL + VME_A16_MSTR_SIZE - 1,
VME_A16_MSTR_SIZE / 0x400);
#endif
#if VME_A24_MSTR_SIZE
printf ("VME A24 0x%08x - 0x%08x mapped to 0x%08x - 0x%08x (%d MB)\n",
VME_A24_MSTR_BUS, VME_A24_MSTR_BUS + VME_A24_MSTR_SIZE - 1,
VME_A24_MSTR_LOCAL, VME_A24_MSTR_LOCAL + VME_A24_MSTR_SIZE - 1,
VME_A24_MSTR_SIZE / 0x100000);
#endif
#if VME_CRCSR_MSTR_SIZE
printf ("VME CSR 0x%08x - 0x%08x mapped to 0x%08x - 0x%08x (%d MB)\n",
VME_CRCSR_MSTR_BUS, VME_CRCSR_MSTR_BUS + VME_CRCSR_MSTR_SIZE - 1,
VME_CRCSR_MSTR_LOCAL, VME_CRCSR_MSTR_LOCAL + VME_CRCSR_MSTR_SIZE - 1,
VME_CRCSR_MSTR_SIZE / 0x100000);
#endif
#if VME_A32_MSTR_SIZE
printf ("VME A32 0x%08x - 0x%08x mapped to 0x%08x - 0x%08x (%d MB)\n",
VME_A32_MSTR_BUS, VME_A32_MSTR_BUS + VME_A32_MSTR_SIZE - 1,
VME_A32_MSTR_LOCAL, VME_A32_MSTR_LOCAL + VME_A32_MSTR_SIZE - 1,
VME_A32_MSTR_SIZE / 0x100000);
#endif
return OK;
}
From what I see from @dirk-zimoch and @anjohnson it doesn't appear that vxWorks provides a uniform interface to show VME configuration. The RTEMS BSPs (by @till-s) show almost all window configuration at startup, and could be made to do so again by calling eg. BSP_VMEOutboundPortsShow(FILE*)
.
... Reading the live config would be better, I think. ...
I'm coming to this conclusion as well.
fyi. I would do this using the PCI handling code already in devlib2. So VME bridge inspection would be added to libepicspci instead of libepicsvme as I don't want to introduce a hard dependency vme -> pci.
In VxWorks, the VME bus bridge driver is part of the BSP, not part of the VxWorks kernel. Thus, there is no "standard" way to query its configuration. Also, because VxWorks sets the mapping statically at boot time, I guess nobody at WindRiver saw a need for an interface to read that setting at run time. Even the sysBusToLocalAdrs
and sysLocalToBusAdrs
functions (which are standard interfaces defined in sysLib.h) have implementations in the BSP that use the compile-time macros (just as my vmeMapShow
function above). These macros are available to the BSP but not necessarily to EPICS, because EPICS has no BSP dependency (and should not have).
It should be possible to write EPICS drivers for the two VME bus bridge chips I know about, Universe II and Tempe Tsi148. For example the mv6100 BSP already has tempeWinShow
which uses getInWinVals()
and getOutWinVals()
to dynamically read the configuration. But again such functions would need BSP specific knowledge of non-standard functions like get*WinVals()
or at least sysTempeBaseAdrsGet()
or variables like univBaseAdrs
to find the chips.
The BSPs finds the Universe chip by PCI id 0x000010e3
but the Tempe chip at bus 0, dev 5, function 0 on the mv6100.
PS: devPCIShow
finds the Universe II as vendor:device 10e3:0000 rev 01
.
Currently I have no IOC with a Tempe Tsi148 running to see the PCI id. But according to the manual it should be 10e3:0148 rev 01
.
Even the sysBusToLocalAdrs and sysLocalToBusAdrs functions (which are standard interfaces defined in sysLib.h) have implementations in the BSP that use the compile-time macros (just as my vmeMapShow function above).
That's not the case with the newer PowerPC BSPs for the Tempe chip, the mostly-standard sysTempeMap.c which comes with the Motorola/Emerson/SmartEmbedded BSPs has a routine that captures the inbound and outbound window registers into an array which is then used by the address conversion routines (the capture routine is called after making any window changes using the internal routines for that). My sysVmeMapShow() routines also read the registers directly rather than relying on the macro values.
You are right, I see it even in the old VxWorks 5.5 BSP for mv6100. I do not have any mv6100 in use currently. I am more familiar with mv5100 and mv2300, both with Universe II. As the function is in the BSP, there is unfortunately no "standard" way to do it. The programmer "scb" who wrote the Tempe driver in 2003 did it differently that the programmer "srr" who wrote the Universe driver in 1998. And nobody at WR seemed to have any intention to unify the way to access VME windows in VxWorks in the last 20 years. (Or to spend any effort on old BSPs or old VxWorks versions, including all 6.x, understandably.)