assemblyioelfsubroutinesparc

How to set TBR in a sparc V8 processor?


I apologize if this is a very basic question, and I'm afraid I don't know to whom or where I can ask such questions.

I'm working on a sparc v8 simulator project and I'm currently stuck at handling traps. The V8 manual doesn't help me and I have no idea what 'trap' has what 'trap number'.

The comments on this question give me some idea, but not the whole picture. This page explains trap entry, but I'm still stuck with the same problem. I don't know what initial value to give TBR and how to calculate TBR value based on 'trap number'.

I'm starting with TBR register set to 0. If my ELF file has, say ta 1, what are the steps to follow?


Solution

  • How to set TBR in a sparc V8 processor?

    The instruction doing this is named wrtbr value (e.g. wrtbr %i5) in some assemblers and mov value, %tbr (e.g. mov %i4, %tbr) in other assemblers.

    Only the operating system can change the TBR register; trying to access this register from user mode (an application) will cause a type 3 exception.

    If you are working with a Sparc emulator that only emulates the CPU on application level (I have written a similar one some years ago), this instruction will not be supported at all because only the OS can execute it.

    Note that you only write the "TBA" field (bits 31...12) of the "TBR" register; the "tt" field (bits 11...4) are written by the CPU when a trap/interrupt/exception occurs.

    ... what 'trap' has what 'trap number'.

    The "Sparc architecture manual Version 8" lists the values of "tt" (bits 11..4 of the TBR register) in table 7-1 on page 76:

    0x01      Instruction access exception
    0x02      Illegal instruction
    0x03      Privileged instruction
    0x04      Floating point disabled
    0x05      Window overflow
    0x06      Window underflow
    0x07      Memory address not aligned
    0x08      Floating point exception
    0x09      Data access exception
    0x0A      Tag overflow
    0x0B      Watch point detected
    0x11-0x1F Hardware interrupts
    0x20      Register access error
    0x21      Instruction access error
    0x24      Coprocessor disabled
    0x25      Unimplemented FLUSH
    0x28      Coprocessor exception
    0x29      Data access error
    0x2A      Division by zero
    0x2B      Data store error
    0x2C      Data access MMU miss
    0x3C      Instruction access MMU miss
    0x60-0x7F CPU or hardware specific
    0x80-0xFF "txx" instructions (example: "ta 0x25" => 0x80+0x25 = 0xA5)
    

    I don't know what initial value to give TBR and how to calculate TBR value based on 'trap number'.

    You have to implement the 256 interrupt handlers, each of 4 instructions length, and place these 256 interrupt handlers in some memory area of 4096 bytes length whose address is a multiple of 4096.

    (Because a real exception handler is more than 4 instructions long, most of the 4-instruction exception handlers will more or less be jump instructions to the actual exception handler.)

    Example: Your 256 interrupt handlers are located at address 0x12345000.

    You write this address (0x12345000 in the example) to the TBR register.

    If some trap occurs, the trap number will be multiplied by 16 and added to that address. The result is the address of the interrupt handler.

    Example:

    When the instruction ta 5 is executed, trap number (5+0x80) occurs.

    0x12345000+(5+0x80)*16 = 0x12345850.

    The CPU will execute the trap handler at address 0x12345850.

    Let's say some save instruction is executed and there is no more space in the internal registers. Then a "window overflow" (trap number 5) occurs.

    0x12345000+5*16 = 0x12345050.

    The CPU will execute the trap handler at address 0x12345050.

    I'm starting with TBR register set to 0. If my ELF file has, say ta 1, what are the steps to follow?

    This would mean that the CPU executes the code at address 0+(0x80+1)*16 = 0x810.

    However, as I already said, you cannot access the TBR register from an application but only from the OS...