How to determine the version of a Rasberry Pi board using the A / C handle assembly?

I am developing a test kernel for Raspberry Pi devices. In this case, I need to configure UART so that we can write data to the device and receive data that should be processed by the kernel. I want the test core to work on multiple Raspberry Pi devices. However, there is a small problem:

UART addresses Difference between versions. For example, the address for the RPi 1 UART GPIO line:

0x20200000

But the address for the GPIO URI on the RPi 2 and RPi 3 lines is:

0x3F200000

Naturally, this means that there must be two separate functions UART_INIT: 1 for devices of the line RPi 1 and 1 for RPi 2 and higher.

Here is an example UART processing code. This code is modified from the code provided by osdev:

void uart_init_rpi1()
{
    // Disable UART0.
    mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_CR, 0x00000000);
    // Setup the GPIO pin 14 && 15.

    // Disable pull up/down for all GPIO pins & delay for 150 cycles.
    mmio_write(PD_GPPUD_RPI1, 0x00000000);
    delay(150);

    // Disable pull up/down for pin 14,15 & delay for 150 cycles.
    mmio_write(PD_GPPUDCLK0_RPI1, (1 << 14) | (1 << 15));
    delay(150);

    // Write 0 to GPPUDCLK0 to make it take effect.
    mmio_write(PD_GPPUDCLK0_RPI1, 0x00000000);

    // Clear pending interrupts.
    mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_ICR, 0x7FF);

    // Set integer & fractional part of baud rate.
    // Divider = UART_CLOCK/(16 * Baud)
    // Fraction part register = (Fractional part * 64) + 0.5
    // UART_CLOCK = 3000000; Baud = 115200.

    // Divider = 3000000 / (16 * 115200) = 1.627 = ~1.
    // Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40.
    mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_IBRD, 1);
    mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_FBRD, 40);

    // Enable FIFO & 8 bit data transmissio (1 stop bit, no parity).
    mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_LCRH, (1 << 4) | (1 << 5) | (1 << 6));

    // Mask all interrupts.
    mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_IMSC, (1 << 1) | (1 << 4) | (1 << 5) | (1 << 6) |
                       (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10));

    // Enable UART0, receive & transfer part of UART.
    mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_CR, (1 << 0) | (1 << 8) | (1 << 9));
}

UART INIT RPi 2 RPi 3. UART INIT , . , . , . , , ​​ RPi 1, RPi 2-3 RPi, ODROID OC-2, . - , UART , , . , , - , RPi Revision . x86 _RTDSC, , NON-x86/x86-64.

, , , : , , C, , /? ​​, C, C volatile assembly.

+4
2

pi ​​cpu ( armv6, armv7, armv8), .

.globl GETCPUID
GETCPUID:
    mrc p15,0,r0,c0,c0,0
    bx lr

PI3 0x410FD034
PI2 0x410FC075
PI1/Zero 0x410FB767

if((id&0xFFFFFFFF)==0x410FB767) PBASE=0x20000000;
else                            PBASE=0x3F000000;
+3

ARM RP1, RP2 RP2 v1.2 () , : ARM11, Cortex-A7 Cortex-A53.

ARM CP15 , , ARM .

MRC p15,0,<Rd>,c0,c0,0; reads Main ID register

ARM11 0xB76
Cortex-A7 0xC07
Cortex-A53 0xD03.

, infocenter.arm( , )

:
ARM1176JZF-S (PI-1):
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0301h/Bgbiddeb.html

Cortex-A53 (PI-2 v1.2 ): http://infocenter.arm.com/help/topic/com.arm.doc.ddi0500g/BABFEABI.html

, .

[ ]

+1

Source: https://habr.com/ru/post/1669054/


All Articles