Browse Source

makefiles: Add support for xtensa-embedded target.

git-svn-id: trunk@44332 -
Jeppe Johansen 5 years ago
parent
commit
3189e4245d
6 changed files with 283 additions and 4 deletions
  1. 1 0
      .gitattributes
  2. 3 0
      Makefile.fpc
  3. 10 4
      compiler/Makefile.fpc
  4. 6 0
      compiler/utils/fpc.pp
  5. 9 0
      rtl/embedded/Makefile.fpc
  6. 254 0
      rtl/embedded/xtensa/esp8266.pp

+ 1 - 0
.gitattributes

@@ -10613,6 +10613,7 @@ rtl/embedded/system.pp svneol=native#text/plain
 rtl/embedded/systhrd.inc svneol=native#text/plain
 rtl/embedded/systhrd.inc svneol=native#text/plain
 rtl/embedded/sysutils.pp svneol=native#text/pascal
 rtl/embedded/sysutils.pp svneol=native#text/pascal
 rtl/embedded/tthread.inc svneol=native#text/plain
 rtl/embedded/tthread.inc svneol=native#text/plain
+rtl/embedded/xtensa/esp8266.pp svneol=native#text/pascal
 rtl/emx/Makefile svneol=native#text/plain
 rtl/emx/Makefile svneol=native#text/plain
 rtl/emx/Makefile.fpc svneol=native#text/plain
 rtl/emx/Makefile.fpc svneol=native#text/plain
 rtl/emx/dos.pas svneol=native#text/plain
 rtl/emx/dos.pas svneol=native#text/plain

+ 3 - 0
Makefile.fpc

@@ -91,6 +91,9 @@ endif
 ifeq ($(CPU_TARGET),riscv64)
 ifeq ($(CPU_TARGET),riscv64)
 PPSUF=rv64
 PPSUF=rv64
 endif
 endif
+ifeq ($(CPU_TARGET),xtensa)
+PPSUF=xtensa
+endif
 
 
 # cross compilers uses full cpu_target, not just ppc-suffix
 # cross compilers uses full cpu_target, not just ppc-suffix
 # (except if the target cannot run a native compiler)
 # (except if the target cannot run a native compiler)

+ 10 - 4
compiler/Makefile.fpc

@@ -32,7 +32,7 @@ fpcdir=..
 unexport FPC_VERSION FPC_COMPILERINFO
 unexport FPC_VERSION FPC_COMPILERINFO
 
 
 # Which platforms are ready for inclusion in the cycle
 # Which platforms are ready for inclusion in the cycle
-CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086 aarch64 sparc64 riscv32 riscv64
+CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086 aarch64 sparc64 riscv32 riscv64 xtensa
 
 
 # All supported targets used for clean
 # All supported targets used for clean
 ALLTARGETS=$(CYCLETARGETS)
 ALLTARGETS=$(CYCLETARGETS)
@@ -89,6 +89,9 @@ endif
 ifdef RISCV64
 ifdef RISCV64
 PPC_TARGET=riscv64
 PPC_TARGET=riscv64
 endif
 endif
+ifdef XTENSA
+PPC_TARGET=xtensa
+endif
 
 
 # Default is to generate a compiler for the same
 # Default is to generate a compiler for the same
 # platform as CPU_TARGET (a native compiler)
 # platform as CPU_TARGET (a native compiler)
@@ -224,6 +227,9 @@ endif
 ifeq ($(CPC_TARGET),riscv64)
 ifeq ($(CPC_TARGET),riscv64)
 CPUSUF=rv64
 CPUSUF=rv64
 endif
 endif
+ifeq ($(CPC_TARGET),xtensa)
+CPUSUF=xtensa
+endif
 
 
 # Do not define the default -d$(CPU_TARGET) because that
 # Do not define the default -d$(CPU_TARGET) because that
 # will conflict with our -d$(CPC_TARGET)
 # will conflict with our -d$(CPC_TARGET)
@@ -585,8 +591,8 @@ endif
 # cpu targets
 # cpu targets
 #####################################################################
 #####################################################################
 
 
-PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 mips mipsel avr jvm i8086 aarch64 sparc64 riscv32 riscv64
-PPC_SUFFIXES=386 68k ppc sparc arm armeb x64 ppc64 mips mipsel avr jvm 8086 a64 sparc64 rv32 rv64
+PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 mips mipsel avr jvm i8086 aarch64 sparc64 riscv32 riscv64 xtensa
+PPC_SUFFIXES=386 68k ppc sparc arm armeb x64 ppc64 mips mipsel avr jvm 8086 a64 sparc64 rv32 rv64 xtensa
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 SYMLINKINSTALL_TARGETS=$(addsuffix _symlink_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 SYMLINKINSTALL_TARGETS=$(addsuffix _symlink_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 
 
@@ -984,7 +990,7 @@ ifeq ($(OS_SOURCE),win64)
   EXCLUDE_80BIT_TARGETS=1
   EXCLUDE_80BIT_TARGETS=1
 endif
 endif
 
 
-ifneq ($(findstring $(CPU_SOURCE),aarch64 arm avr jvm m68k mips mipsel powerpc powerpc64 sparc sparc64 riscv32 riscv64),)
+ifneq ($(findstring $(CPU_SOURCE),aarch64 arm avr jvm m68k mips mipsel powerpc powerpc64 sparc sparc64 riscv32 riscv64 xtensa),)
   EXCLUDE_80BIT_TARGETS=1
   EXCLUDE_80BIT_TARGETS=1
 endif
 endif
 
 

+ 6 - 0
compiler/utils/fpc.pp

@@ -180,6 +180,10 @@ program fpc;
      ppcbin:='ppcrv64';
      ppcbin:='ppcrv64';
      processorname:='riscv64';
      processorname:='riscv64';
 {$endif riscv64}
 {$endif riscv64}
+{$ifdef xtensa}
+     ppcbin:='ppcxtensa';
+     processorname:='xtensa';
+{$endif xtensa}
      versionstr:='';                      { Default is just the name }
      versionstr:='';                      { Default is just the name }
      if ParamCount = 0 then
      if ParamCount = 0 then
        begin
        begin
@@ -263,6 +267,8 @@ program fpc;
                              cpusuffix:='sparc64'
                              cpusuffix:='sparc64'
                            else if processorstr='x86_64' then
                            else if processorstr='x86_64' then
                              cpusuffix:='x64'
                              cpusuffix:='x64'
+                           else if processorstr='xtensa' then
+                             cpusuffix:='xtensa'
                            else
                            else
                              error('Illegal processor type "'+processorstr+'"');
                              error('Illegal processor type "'+processorstr+'"');
 
 

+ 9 - 0
rtl/embedded/Makefile.fpc

@@ -221,6 +221,15 @@ $(error No CPUs enabled for given SUBARCH, pass either a SUBARCH or set CPU_UNIT
 endif
 endif
 endif
 endif
 
 
+ifeq ($(ARCH),xtensa)
+CPU_SPECIFIC_COMMON_UNITS=sysutils math classes fgl macpas typinfo types rtlconsts getopts lineinfo
+CPU_UNITS=esp8266
+CPU_UNITS_DEFINED=1
+ifeq ($(CPU_UNITS_DEFINED),)
+$(error No CPUs enabled for given SUBARCH, pass either a SUBARCH or set CPU_UNITS_DEFINED=1 if you know what you are doing)
+endif
+endif
+
 # Paths
 # Paths
 OBJPASDIR=$(RTL)/objpas
 OBJPASDIR=$(RTL)/objpas
 GRAPHDIR=$(INC)/graph
 GRAPHDIR=$(INC)/graph

+ 254 - 0
rtl/embedded/xtensa/esp8266.pp

@@ -0,0 +1,254 @@
+unit esp8266;
+
+interface
+
+const
+  //unit: Hz
+  APB_CLK_FREQ = 80*1000000;
+  UART_CLK_FREQ = APB_CLK_FREQ;
+  //divided by 256
+  TIMER_CLK_FREQ = (APB_CLK_FREQ shr 8);
+
+  //Peripheral device base address
+  PERIPHS_DPORT_BASEADDR = $3ff00000;
+  PERIPHS_GPIO_BASEADDR  = $60000300;
+  PERIPHS_TIMER_BASEDDR  = $60000600;
+  PERIPHS_RTC_BASEADDR   = $60000700;
+  PERIPHS_IO_MUX         = $60000800;
+
+  //Interrupt remap control registers
+  EDGE_INT_ENABLE_REG = (PERIPHS_DPORT_BASEADDR+$04);
+  // TM1_EDGE_INT_ENABLE() = SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1);
+  // TM1_EDGE_INT_DISABLE() = CLEAR_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1);
+
+  //GPIO reg
+  // GPIO_REG_READ(reg) = READ_PERI_REG(PERIPHS_GPIO_BASEADDR + reg);
+  // GPIO_REG_WRITE(reg, val)                 = WRITE_PERI_REG(PERIPHS_GPIO_BASEADDR + reg, val);
+  GPIO_OUT_ADDRESS = $00;
+  GPIO_OUT_W1TS_ADDRESS = $04;
+  GPIO_OUT_W1TC_ADDRESS = $08;
+
+  GPIO_ENABLE_ADDRESS = $0c;
+  GPIO_ENABLE_W1TS_ADDRESS = $10;
+  GPIO_ENABLE_W1TC_ADDRESS = $14;
+  GPIO_OUT_W1TC_DATA_MASK = $0000ffff;
+
+  GPIO_IN_ADDRESS = $18;
+
+  GPIO_STATUS_ADDRESS = $1c;
+  GPIO_STATUS_W1TS_ADDRESS = $20;
+  GPIO_STATUS_W1TC_ADDRESS = $24;
+  GPIO_STATUS_INTERRUPT_MASK = $0000ffff;
+
+  GPIO_RTC_CALIB_SYNC = PERIPHS_GPIO_BASEADDR+$6c;
+  //first write to zero, then to one to start
+  RTC_CALIB_START = BIT31;
+  //max 8ms
+  RTC_PERIOD_NUM_MASK = $3ff;
+  GPIO_RTC_CALIB_VALUE = PERIPHS_GPIO_BASEADDR+$70;
+  //after measure, flag to one, when start from zero to one, turn to zero
+  RTC_CALIB_RDY_S = 31;
+  RTC_CALIB_VALUE_MASK = $fffff;
+
+  GPIO_PIN0_ADDRESS = $28;
+
+  GPIO_ID_PIN0 = 0;
+  // GPIO_ID_PIN(n) = (GPIO_ID_PIN0+(n));
+  GPIO_LAST_REGISTER_ID = 15;
+  GPIO_ID_NONE = $ffffffff;
+
+  GPIO_PIN_COUNT = 16;
+
+  GPIO_PIN_CONFIG_MSB = 12;
+  GPIO_PIN_CONFIG_LSB = 11;
+  GPIO_PIN_CONFIG_MASK = $00001800;
+  // GPIO_PIN_CONFIG_GET(x) = (((x) and GPIO_PIN_CONFIG_MASK)  shr  GPIO_PIN_CONFIG_LSB);
+  // GPIO_PIN_CONFIG_SET(x) = (((x)  shl  GPIO_PIN_CONFIG_LSB) and GPIO_PIN_CONFIG_MASK);
+
+  GPIO_WAKEUP_ENABLE = 1;
+  GPIO_WAKEUP_DISABLE = (not GPIO_WAKEUP_ENABLE);
+  GPIO_PIN_WAKEUP_ENABLE_MSB = 10;
+  GPIO_PIN_WAKEUP_ENABLE_LSB = 10;
+  GPIO_PIN_WAKEUP_ENABLE_MASK = $00000400;
+  // GPIO_PIN_WAKEUP_ENABLE_GET(x) = (((x) and GPIO_PIN_WAKEUP_ENABLE_MASK)  shr  GPIO_PIN_WAKEUP_ENABLE_LSB);
+  // GPIO_PIN_WAKEUP_ENABLE_SET(x) = (((x)  shl  GPIO_PIN_WAKEUP_ENABLE_LSB) and GPIO_PIN_WAKEUP_ENABLE_MASK);
+
+  GPIO_PIN_INT_TYPE_MASK = $380;
+  GPIO_PIN_INT_TYPE_MSB = 9;
+  GPIO_PIN_INT_TYPE_LSB = 7;
+  // GPIO_PIN_INT_TYPE_GET(x) = (((x) and GPIO_PIN_INT_TYPE_MASK)  shr  GPIO_PIN_INT_TYPE_LSB);
+  // GPIO_PIN_INT_TYPE_SET(x) = (((x)  shl  GPIO_PIN_INT_TYPE_LSB) and GPIO_PIN_INT_TYPE_MASK);
+
+  GPIO_PAD_DRIVER_ENABLE = 1;
+  GPIO_PAD_DRIVER_DISABLE = (not GPIO_PAD_DRIVER_ENABLE);
+  GPIO_PIN_PAD_DRIVER_MSB = 2;
+  GPIO_PIN_PAD_DRIVER_LSB = 2;
+  GPIO_PIN_PAD_DRIVER_MASK = $00000004;
+  // GPIO_PIN_PAD_DRIVER_GET(x) = (((x) and GPIO_PIN_PAD_DRIVER_MASK)  shr  GPIO_PIN_PAD_DRIVER_LSB);
+  // GPIO_PIN_PAD_DRIVER_SET(x) = (((x)  shl  GPIO_PIN_PAD_DRIVER_LSB) and GPIO_PIN_PAD_DRIVER_MASK);
+
+  GPIO_AS_PIN_SOURCE = 0;
+  SIGMA_AS_PIN_SOURCE = (not GPIO_AS_PIN_SOURCE);
+  GPIO_PIN_SOURCE_MSB = 0;
+  GPIO_PIN_SOURCE_LSB = 0;
+  GPIO_PIN_SOURCE_MASK = $00000001;
+  // GPIO_PIN_SOURCE_GET(x) = (((x) and GPIO_PIN_SOURCE_MASK)  shr  GPIO_PIN_SOURCE_LSB);
+  // GPIO_PIN_SOURCE_SET(x) = (((x)  shl  GPIO_PIN_SOURCE_LSB) and GPIO_PIN_SOURCE_MASK);
+
+  // TIMER reg
+  // RTC_REG_READ(addr) = READ_PERI_REG(PERIPHS_TIMER_BASEDDR + addr);
+  // RTC_REG_WRITE(addr, val) =                WRITE_PERI_REG(PERIPHS_TIMER_BASEDDR + addr, val);
+  // RTC_CLR_REG_MASK(reg, mask) =      CLEAR_PERI_REG_MASK(PERIPHS_TIMER_BASEDDR +reg, mask);
+  // Returns the current time according to the timer timer.
+  // NOW() = RTC_REG_READ(FRC2_COUNT_ADDRESS);
+
+  //load initial_value to timer1
+  FRC1_LOAD_ADDRESS = $00;
+
+  //timer1's counter value(count from initial_value to 0)
+  FRC1_COUNT_ADDRESS = $04;
+
+  FRC1_CTRL_ADDRESS = $08;
+
+  //clear timer1's interrupt when write this address
+  FRC1_INT_ADDRESS = $0c;
+  FRC1_INT_CLR_MASK = $00000001;
+
+  //timer2's counter value(count from initial_value to 0)
+  FRC2_COUNT_ADDRESS = $24;
+
+  //RTC reg
+  REG_RTC_BASE = PERIPHS_RTC_BASEADDR;
+
+  RTC_STORE0 = (REG_RTC_BASE + $030);
+  RTC_STORE1 = (REG_RTC_BASE + $034);
+  RTC_STORE2 = (REG_RTC_BASE + $038);
+  RTC_STORE3 = (REG_RTC_BASE + $03C);
+
+  RTC_GPIO_OUT = (REG_RTC_BASE + $068);
+  RTC_GPIO_ENABLE = (REG_RTC_BASE + $074);
+  RTC_GPIO_IN_DATA = (REG_RTC_BASE + $08C);
+  RTC_GPIO_CONF = (REG_RTC_BASE + $090);
+  PAD_XPD_DCDC_CONF = (REG_RTC_BASE + $0A0);
+
+  //PIN Mux reg
+  PERIPHS_IO_MUX_FUNC = $13;
+  PERIPHS_IO_MUX_FUNC_S = 4;
+  PERIPHS_IO_MUX_PULLUP = BIT7;
+  PERIPHS_IO_MUX_PULLUP2 = BIT6;
+  PERIPHS_IO_MUX_SLEEP_PULLUP = BIT3;
+  PERIPHS_IO_MUX_SLEEP_PULLUP2 = BIT2;
+  PERIPHS_IO_MUX_SLEEP_OE = BIT1;
+  PERIPHS_IO_MUX_OE = BIT0;
+
+  PERIPHS_IO_MUX_CONF_U = (PERIPHS_IO_MUX + $00);
+  SPI0_CLK_EQU_SYS_CLK = BIT8;
+  SPI1_CLK_EQU_SYS_CLK = BIT9;
+  PERIPHS_IO_MUX_MTDI_U = (PERIPHS_IO_MUX + $04);
+  FUNC_GPIO12 = 3;
+  PERIPHS_IO_MUX_MTCK_U = (PERIPHS_IO_MUX + $08);
+  FUNC_GPIO13 = 3;
+  PERIPHS_IO_MUX_MTMS_U = (PERIPHS_IO_MUX + $0C);
+  FUNC_GPIO14 = 3;
+  PERIPHS_IO_MUX_MTDO_U = (PERIPHS_IO_MUX + $10);
+  FUNC_GPIO15 = 3;
+  FUNC_U0RTS = 4;
+  PERIPHS_IO_MUX_U0RXD_U = (PERIPHS_IO_MUX + $14);
+  FUNC_GPIO3 = 3;
+  PERIPHS_IO_MUX_U0TXD_U = (PERIPHS_IO_MUX + $18);
+  FUNC_U0TXD = 0;
+  FUNC_GPIO1 = 3;
+  PERIPHS_IO_MUX_SD_CLK_U = (PERIPHS_IO_MUX + $1c);
+  FUNC_SDCLK = 0;
+  FUNC_SPICLK = 1;
+  PERIPHS_IO_MUX_SD_DATA0_U = (PERIPHS_IO_MUX + $20);
+  FUNC_SDDATA0 = 0;
+  FUNC_SPIQ = 1;
+  FUNC_U1TXD = 4;
+  PERIPHS_IO_MUX_SD_DATA1_U = (PERIPHS_IO_MUX + $24);
+  FUNC_SDDATA1 = 0;
+  FUNC_SPID = 1;
+  FUNC_U1RXD = 4;
+  FUNC_SDDATA1_U1RXD = 7;
+  PERIPHS_IO_MUX_SD_DATA2_U = (PERIPHS_IO_MUX + $28);
+  FUNC_SDDATA2 = 0;
+  FUNC_SPIHD = 1;
+  FUNC_GPIO9 = 3;
+  PERIPHS_IO_MUX_SD_DATA3_U = (PERIPHS_IO_MUX + $2c);
+  FUNC_SDDATA3 = 0;
+  FUNC_SPIWP = 1;
+  FUNC_GPIO10 = 3;
+  PERIPHS_IO_MUX_SD_CMD_U = (PERIPHS_IO_MUX + $30);
+  FUNC_SDCMD = 0;
+  FUNC_SPICS0 = 1;
+  PERIPHS_IO_MUX_GPIO0_U = (PERIPHS_IO_MUX + $34);
+  FUNC_GPIO0 = 0;
+  PERIPHS_IO_MUX_GPIO2_U = (PERIPHS_IO_MUX + $38);
+  FUNC_GPIO2 = 0;
+  FUNC_U1TXD_BK = 2;
+  FUNC_U0TXD_BK = 4;
+  PERIPHS_IO_MUX_GPIO4_U = (PERIPHS_IO_MUX + $3C);
+  FUNC_GPIO4 = 0;
+  PERIPHS_IO_MUX_GPIO5_U = (PERIPHS_IO_MUX + $40);
+  FUNC_GPIO5 = 0;
+
+  // PIN_PULLUP_DIS(PIN_NAME) = CLEAR_PERI_REG_MASK(PIN_NAME, PERIPHS_IO_MUX_PULLUP);
+  // PIN_PULLUP_EN(PIN_NAME) = SET_PERI_REG_MASK(PIN_NAME, PERIPHS_IO_MUX_PULLUP);
+
+implementation
+
+var
+  _stack_top: record end; external name '_stack_top';
+  _data: record end; external name '_data';
+  _edata: record end; external name '_edata';
+  _text_start: record end; external name '_text_start';
+  _etext: record end; external name '_etext';
+  _bss_start: record end; external name '_bss_start';
+  _bss_end: record end; external name '_bss_end';
+
+procedure Pascalmain; external name 'PASCALMAIN';
+
+procedure HaltProc; assembler; nostackframe; public name'_haltproc';
+asm
+.Lloop:
+   b .Lloop
+end;
+
+procedure Startup;
+var
+  psrc,pdst,pend: plongword;
+begin
+  // Copy .text
+  psrc:=@_etext;
+  pdst:=@_data;
+  pend:=@_edata;
+  while pdst<pend do
+    begin
+      pdst^:=psrc^;
+      inc(pdst);
+      inc(psrc);
+    end;
+
+  // Clear .bss
+  pend:=@_bss_end;
+  while pdst<pend do
+    begin
+      pdst^:=0;
+      inc(pdst);
+    end;
+  
+  PascalMain;
+  Haltproc;
+end;
+
+procedure LowLevelStartup; assembler; nostackframe;
+asm
+  l32r a1, .Lstack_ptr
+
+  j Startup
+
+.Lstack_ptr:
+  .long _stack_top
+end;
+
+end.