ソースを参照

* patch by Robert Roland to support the RaspberryPi 2 as a bare metal embedded target, resolves #35236

git-svn-id: trunk@44027 -
florian 5 年 前
コミット
7b4292c94e

+ 1 - 0
.gitattributes

@@ -10322,6 +10322,7 @@ rtl/embedded/arm/mk22f51212.pp svneol=native#text/pascal
 rtl/embedded/arm/mk64f12.pp svneol=native#text/pascal
 rtl/embedded/arm/nrf51.pp svneol=native#text/pascal
 rtl/embedded/arm/nrf52.pp svneol=native#text/pascal
+rtl/embedded/arm/raspi2.pp svneol=native#text/pascal
 rtl/embedded/arm/sam3x8e.pp svneol=native#text/pascal
 rtl/embedded/arm/sc32442b.pp svneol=native#text/pascal
 rtl/embedded/arm/stm32f0xx.pp svneol=native#text/plain

+ 6 - 0
compiler/arm/cpuinfo.pas

@@ -508,6 +508,9 @@ Type
       ct_nrf52832_xxaa,
       ct_nrf52840_xxaa,
 
+      { Raspberry Pi 2 }
+      ct_raspi2,
+
       // generic Thumb2 target
       ct_thumb2bare
      );
@@ -1025,6 +1028,9 @@ Const
       (controllertypestr:'NRF52832_XXAA'; controllerunitstr:'NRF52'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000; flashsize:$00080000; srambase:$20000000; sramsize:$00010000),
       (controllertypestr:'NRF52840_XXAA'; controllerunitstr:'NRF52'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000; flashsize:$00080000; srambase:$20000000; sramsize:$00010000),
       
+      { Raspberry Pi 2 }
+      (controllertypestr:'RASPI2'; controllerunitstr:'RASPI2'; cputype:cpu_armv7a; fputype:fpu_vfpv4; flashbase:$00000000; flashsize:$00000000; srambase:$00008000; sramsize:$10000000),
+
       { Bare bones }
       (controllertypestr:'THUMB2_BARE';	controllerunitstr:'THUMB2_BARE';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$20000000;	sramsize:$00000400)
     );

+ 4 - 0
compiler/systems/t_embed.pas

@@ -618,6 +618,10 @@ begin
       ct_nrf52840_xxaa,
       
       ct_sc32442b,
+
+      { Raspberry Pi 2 }
+      ct_raspi2,
+
       ct_thumb2bare:
         begin
          with embedded_controllers[current_settings.controllertype] do

+ 1 - 1
rtl/embedded/Makefile

@@ -376,7 +376,7 @@ CPU_UNITS=lpc8xx lpc11xx lpc122x stm32f0xx nrf51 cortexm0
 CPU_UNITS_DEFINED=1
 endif
 ifeq ($(SUBARCH),armv7a)
-CPU_UNITS=allwinner_a20
+CPU_UNITS=allwinner_a20 raspi2
 CPU_UNITS_DEFINED=1
 endif
 ifeq ($(CPU_UNITS_DEFINED),)

+ 1 - 1
rtl/embedded/Makefile.fpc

@@ -91,7 +91,7 @@ CPU_UNITS=lpc8xx lpc11xx lpc122x stm32f0xx nrf51 cortexm0
 CPU_UNITS_DEFINED=1
 endif
 ifeq ($(SUBARCH),armv7a)
-CPU_UNITS=allwinner_a20
+CPU_UNITS=allwinner_a20 raspi2
 CPU_UNITS_DEFINED=1
 endif
 ifeq ($(CPU_UNITS_DEFINED),)

+ 204 - 0
rtl/embedded/arm/raspi2.pp

@@ -0,0 +1,204 @@
+unit raspi2;
+
+{$goto on}
+{$INLINE ON}
+
+interface
+
+type
+    TBitvector32 = bitpacked array[0..31] of 0..1;
+
+const
+    PeripheralBase = $3F000000;
+
+    GPFSEL1 = PeripheralBase + $00200004;
+    GPSET0 = PeripheralBase + $0020001C;
+    GPCLR0 = PeripheralBase + $00200028;
+    GPPUD = PeripheralBase + $00200094;
+    GPPUDCLK0 = PeripheralBase + $00200098;
+
+    AUX_ENABLES = PeripheralBase + $00215004;
+    AUX_MU_IO_REG = PeripheralBase + $00215040;
+    AUX_MU_IER_REG = PeripheralBase + $00215044;
+    AUX_MU_IIR_REG = PeripheralBase + $00215048;
+    AUX_MU_LCR_REG = PeripheralBase + $0021504C;
+    AUX_MU_MCR_REG = PeripheralBase + $00215050;
+    AUX_MU_LSR_REG = PeripheralBase + $00215054;
+    AUX_MU_MSR_REG = PeripheralBase + $00215058;
+    AUX_MU_SCRATCH = PeripheralBase + $0021505C;
+    AUX_MU_CNTL_REG = PeripheralBase + $00215060;
+    AUX_MU_STAT_REG = PeripheralBase + $00215064;
+    AUX_MU_BAUD_REG = PeripheralBase + $00215068;
+
+implementation
+
+uses
+    consoleio;
+
+procedure _FPC_haltproc; assembler; nostackframe; public name '_haltproc';
+asm
+.Lhalt:
+    wfi
+    b .Lhalt
+end;
+
+procedure DUMMY(Count: DWord);
+var
+    i : DWord;
+begin
+    for i := 0 to Count do
+    begin
+        asm
+            nop
+        end;
+    end;
+end; 
+
+procedure PUT32(Address: DWord; Value: DWord); inline;
+VAR
+    p: ^DWord;
+begin
+    p := POINTER (Address);
+    p^ := Value;
+end;
+
+function GET32(Address: DWord) : DWord; inline;
+VAR
+    p: ^DWord;
+begin
+    p := POINTER (Address);
+    GET32 := p^;
+end;
+
+function UARTLCR(): DWord;
+begin
+    UARTLCR := GET32(AUX_MU_LCR_REG);
+end;
+
+procedure UARTPuts(C: Char);
+begin
+    while True do
+    begin
+        if (GET32(AUX_MU_LSR_REG) and $20) > 0 then break;
+    end;
+
+    PUT32(AUX_MU_IO_REG, DWord(C));
+end;
+
+function UARTGet(): Char;
+begin
+    while True do
+    begin
+        if (GET32(AUX_MU_LSR_REG) and $01) > 0 then break;
+    end;
+
+    UARTGet := Char(GET32(AUX_MU_IO_REG) and $FF);
+end;
+
+procedure UARTFlush();
+begin
+    while True do
+    begin
+        if (GET32(AUX_MU_LSR_REG) and $100) > 0 then break;
+    end;
+end;
+
+function RaspiWrite(ACh: char; AUserData: pointer): boolean;
+begin
+    UARTPuts(ACh);
+
+    RaspiWrite := true;
+end;
+
+function RaspiRead(var ACh: char; AUserData: pointer): boolean;
+begin
+    if (GET32(AUX_MU_LSR_REG) and $01) > 0 then
+    begin
+        ACh := UARTGet();
+    end else
+    begin
+        ACh := #0;
+    end;
+
+    RaspiRead := true;
+end;
+
+procedure UARTInit; public name 'UARTInit';
+var
+    ra: dword;
+begin
+    PUT32(AUX_ENABLES, 1);
+    PUT32(AUX_MU_IER_REG, 0);
+    PUT32(AUX_MU_CNTL_REG, 0);
+    PUT32(AUX_MU_LCR_REG, 3);
+    PUT32(AUX_MU_MCR_REG, 0);
+    PUT32(AUX_MU_IER_REG, 0);
+    PUT32(AUX_MU_IIR_REG, $C6);
+    PUT32(AUX_MU_BAUD_REG, 270);
+    
+    ra := GET32(GPFSEL1);
+    ra := ra AND (not (7 shl 12)); // gpio14
+    ra := ra OR (2 shl 12);  // alt5
+    ra := ra AND (not (7 shl 15)); // gpio15
+    ra := ra OR (2 shl 15);  // alt5
+
+    PUT32(GPFSEL1, ra);
+    PUT32(GPPUD, 0);
+    
+    Dummy(500);
+
+    PUT32(GPPUDCLK0, ((1 shl 14) OR (1 shl 15)));
+
+    Dummy(500);
+
+    PUT32(GPPUDCLK0, 0);
+    PUT32(AUX_MU_CNTL_REG, 3);
+end;
+
+{$ifndef CUSTOM_ENTRY}
+procedure PASCALMAIN; external name 'PASCALMAIN';
+
+var
+    _stack_top: record end; external name '_stack_top';
+
+{ This start makes sure we only execute on core 0 - the others will halt }
+procedure _FPC_start; assembler; nostackframe;
+label
+    _start;
+asm
+    .init
+    .align 16
+    .globl _start
+_start:
+    // enable fpu
+    .long 0xee110f50      // mrc p15, 0, r0, c1, c0, 2
+    orr r0, r0, #0x300000 // single precision
+    orr r0, r0, #0xC00000 // double precision
+    .long 0xee010f50      // mcr p15, 0, r0, c1, c0, 2
+    mov r0, #0x40000000
+    .long 0xeee80a10      // fmxr fpexc, r0
+
+    .long 0xee100fb0      // mrc p15,0,r0,c0,c0,5 - find the core ID
+    mov r1, #0xFF
+    ands r1, r1, r0
+    bne _FPC_haltproc
+
+    ldr r0, .L_stack_top
+    mov sp, r0
+
+    bl UARTInit
+    bl PASCALMAIN
+    bl _FPC_haltproc
+.L_stack_top:
+    .long _stack_top
+    .text
+end;
+{$endif CUSTOM_ENTRY}
+
+begin
+    OpenIO(Input, @RaspiWrite, @RaspiRead, fmInput, nil);
+    OpenIO(Output, @RaspiWrite, @RaspiRead, fmOutput, nil);
+    OpenIO(ErrOutput, @RaspiWrite, @RaspiRead, fmOutput, nil);
+    OpenIO(StdOut, @RaspiWrite, @RaspiRead, fmOutput, nil);
+    OpenIO(StdErr, @RaspiWrite, @RaspiRead, fmOutput, nil);
+end.