makefiles: Add support for xtensa-embedded target.

git-svn-id: trunk@44332 -
This commit is contained in:
Jeppe Johansen 2020-03-21 20:59:33 +00:00
parent 30a4f667c1
commit 3189e4245d
6 changed files with 283 additions and 4 deletions

1
.gitattributes vendored
View File

@ -10613,6 +10613,7 @@ rtl/embedded/system.pp svneol=native#text/plain
rtl/embedded/systhrd.inc svneol=native#text/plain
rtl/embedded/sysutils.pp svneol=native#text/pascal
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.fpc svneol=native#text/plain
rtl/emx/dos.pas svneol=native#text/plain

View File

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

View File

@ -32,7 +32,7 @@ fpcdir=..
unexport FPC_VERSION FPC_COMPILERINFO
# 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
ALLTARGETS=$(CYCLETARGETS)
@ -89,6 +89,9 @@ endif
ifdef RISCV64
PPC_TARGET=riscv64
endif
ifdef XTENSA
PPC_TARGET=xtensa
endif
# Default is to generate a compiler for the same
# platform as CPU_TARGET (a native compiler)
@ -224,6 +227,9 @@ endif
ifeq ($(CPC_TARGET),riscv64)
CPUSUF=rv64
endif
ifeq ($(CPC_TARGET),xtensa)
CPUSUF=xtensa
endif
# Do not define the default -d$(CPU_TARGET) because that
# will conflict with our -d$(CPC_TARGET)
@ -585,8 +591,8 @@ endif
# 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)))
SYMLINKINSTALL_TARGETS=$(addsuffix _symlink_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
@ -984,7 +990,7 @@ ifeq ($(OS_SOURCE),win64)
EXCLUDE_80BIT_TARGETS=1
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
endif

View File

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

View File

@ -221,6 +221,15 @@ $(error No CPUs enabled for given SUBARCH, pass either a SUBARCH or set CPU_UNIT
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
OBJPASDIR=$(RTL)/objpas
GRAPHDIR=$(INC)/graph

View File

@ -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.