Thursday, August 4, 2011

MIPS Virtualization: VCPU Address Map

            +-------------------------------+ 0xFFFFFFFF
            |...............................| X
            |...............................| V
            |...............................| I
            |...............................| S
            |...............................| O
            |..........X V I S O R..........| R
            |...............................|
            |...............................| A
            |...A D D R R S S S P A C E...  | D
            |...............................| R
            |...............................| S
            |...N O T V I S I B L E TO...   | P
            |......G U E S T V C P U....... | CE
            +-------------------------------+ 0x80000000
            |                               |
            |                               | USEG0/KUSEG0
            |    KSEG2 / USEG0 (ASID Based) |
            |                               |
            |                               |
            +-------------------------------+ 0x40000000
            |                               | 0x3FC00000
            |    KSEG1 / USEG0 (ASID Based) |
            |                               |
            +-------------------------------+ 0x20000000
            |                               |
            |    KSEG0 / USEG0 (ASID Based) |
            |                               |
            +-------------------------------+ 0x00000000
   
                        FIGURE 1.
                 (Address MAP for A VCPU)

Xvisor sees and works on the actual address map as defined by
the MIPS architecure. But for the virtual CPUs (VCPUs) the address
space is different.

The VCPU running the guest OS sees the KSEG0 (Mapped cached region)
starting from 0x00000000. This is where the RAM for the VCPU is
mapped. When VCPU is in Kernel Mode or its EXL bit is set, the 2GB
region starting from 0x00000000 pretends to be the region enclosed
between addresses 0x80000000 - 0xFFFFFFFF on an actual MIPS CPU.
When not running in kernel mode, this 2GB region is the regular
USEG0.

When a VCPU starts, its EXL bit is set and its essentially running
in Kernel mode. So USEG0 of CPU is presented as usual kernel mode
segments by the hypervisor. Since in this mode, 512 MB region
starting at 0x20000000 becomes KSEG1 (mapped, uncached), the VCPU
starts running at virtual address 0x3FC00000 (i.e. it becomes the
start_pc of VCPU).This is the region marked as "ROM" region under
guest in DTS file. The physical address mapped to this virtual
address can be a pointing to a partition in NOR/Boot Flash or it
can be a regular memory. A bootloader typically U-Boot is supposed
to be present at this address. The important thing go note here is
that, since this u-boot will be runnign in guest mode, it can't be
linked at regular boot address i.e. 0xBFC00000. Rather it must be
linked at 0x3FC00000. Since this is the new virtual address where
the VCPU will start executing. This U-boot will also be suitably
modified so that it expects the RAM's physical address in one of
the parameter registers (a0, a1, a2, a4). Also, this modified
u-boot shouldn't try to initialize DRAM. It can though initialize
a uart and other stuff. This U-Boot will then load the guest
operating system.

The point of making USEG0 appear as regular KSEG regions, when
VCPU's EXL bit is set, is that we should be able to boot VCPU's
like a regular MIPS CPUs and do major dirty work in the boot code.
Also, needless to say, this make the picture more comprehensible.