diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2010-02-01 16:16:12 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2010-02-01 16:16:12 +0100 |
commit | 7ca411ecd2dc1c6bc47caad4b1e25a118bd7441b (patch) | |
tree | 716f34c98b8e9a1535a9dc42605644d0793f5161 /arch | |
parent | dc6550ed3be2c47476ccaefdee2277b9360a8ed6 (diff) | |
parent | 976b4be6021569e9808cf83ab7600231d1315307 (diff) | |
download | barebox-7ca411ecd2dc1c6bc47caad4b1e25a118bd7441b.tar.gz barebox-7ca411ecd2dc1c6bc47caad4b1e25a118bd7441b.tar.xz |
Merge branch 'next'
Diffstat (limited to 'arch')
60 files changed, 4751 insertions, 31 deletions
diff --git a/arch/architecture.dox b/arch/architecture.dox index 669c028435..ea00dcdc89 100644 --- a/arch/architecture.dox +++ b/arch/architecture.dox @@ -88,6 +88,7 @@ TODO @li @subpage dev_bf_mach @li @subpage dev_ppc_mach @li @subpage dev_m68k_mach +@li @subpage dev_x86_mach */ diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c091a996a9..9cad224cec 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -31,6 +31,11 @@ config ARCH_AT91RM9200 bool "Atmel AT91RM9200" select CPU_ARM920T +config ARCH_EP93XX + bool "Cirrus Logic EP93xx" + select CPU_ARM920T + select GENERIC_GPIO + config ARCH_IMX bool "Freescale iMX-based" select GENERIC_GPIO @@ -51,6 +56,7 @@ endchoice source arch/arm/cpu/Kconfig source arch/arm/mach-at91/Kconfig source arch/arm/mach-at91rm9200/Kconfig +source arch/arm/mach-ep93xx/Kconfig source arch/arm/mach-imx/Kconfig source arch/arm/mach-netx/Kconfig source arch/arm/mach-omap/Kconfig diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 47b002f9d9..ede20854c8 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -39,6 +39,7 @@ CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y) # by CONFIG_* macro name. machine-$(CONFIG_ARCH_AT91) := at91 machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200 +machine-$(CONFIG_ARCH_EP93XX) := ep93xx machine-$(CONFIG_ARCH_IMX) := imx machine-$(CONFIG_ARCH_NETX) := netx machine-$(CONFIG_ARCH_OMAP) := omap @@ -51,6 +52,14 @@ board-$(CONFIG_MACH_A9M2440) := a9m2440 board-$(CONFIG_MACH_AT91SAM9260EK) := at91sam9260ek board-$(CONFIG_MACH_AT91SAM9263EK) := at91sam9263ek board-$(CONFIG_MACH_ECO920) := eco920 +board-$(CONFIG_MACH_EDB9301) := edb93xx +board-$(CONFIG_MACH_EDB9302) := edb93xx +board-$(CONFIG_MACH_EDB9302A) := edb93xx +board-$(CONFIG_MACH_EDB9307) := edb93xx +board-$(CONFIG_MACH_EDB9307A) := edb93xx +board-$(CONFIG_MACH_EDB93012) := edb93xx +board-$(CONFIG_MACH_EDB9315) := edb93xx +board-$(CONFIG_MACH_EDB9315A) := edb93xx board-$(CONFIG_MACH_EUKREA_CPUIMX27) := eukrea_cpuimx27 board-$(CONFIG_MACH_FREESCALE_MX35_3STACK) := freescale-mx35-3-stack board-$(CONFIG_MACH_FREESCALE_MX25_3STACK) := freescale-mx25-3-stack diff --git a/arch/arm/configs/edb93xx_defconfig b/arch/arm/configs/edb93xx_defconfig new file mode 100644 index 0000000000..d6b4b19f14 --- /dev/null +++ b/arch/arm/configs/edb93xx_defconfig @@ -0,0 +1,236 @@ +# +# Automatically generated make config: don't edit +# barebox version: 2009.12.0 +# Fri Jan 8 17:27:15 2010 +# +CONFIG_ARM=y + +# +# System Type +# +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_AT91RM9200 is not set +CONFIG_ARCH_EP93XX=y +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_S3C24xx is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4T=y + +# +# processor features +# +CONFIG_ARCH_TEXT_BASE=0x05700000 +CONFIG_BOARDINFO="Cirrus Logic EDB9301" +CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET=y + +# +# Cirrus EP93xx System-on-Chip +# +CONFIG_ARCH_EP9301=y +# CONFIG_ARCH_EP9302 is not set +# CONFIG_ARCH_EP9307 is not set +# CONFIG_ARCH_EP9312 is not set +# CONFIG_ARCH_EP9315 is not set +CONFIG_MACH_EDB9301=y +CONFIG_EP93XX_SDRAM_NUM_BANKS=4 +CONFIG_EP93XX_SDRAM_BANK0_BASE=0x00000000 +CONFIG_EP93XX_SDRAM_BANK0_SIZE=0x00800000 +CONFIG_EP93XX_SDRAM_BANK1_BASE=0x01000000 +CONFIG_EP93XX_SDRAM_BANK1_SIZE=0x00800000 +CONFIG_EP93XX_SDRAM_BANK2_BASE=0x04000000 +CONFIG_EP93XX_SDRAM_BANK2_SIZE=0x00800000 +CONFIG_EP93XX_SDRAM_BANK3_BASE=0x05000000 +CONFIG_EP93XX_SDRAM_BANK3_SIZE=0x00800000 +CONFIG_AEABI=y + +# +# Arm specific settings +# +CONFIG_CMD_ARM_CPUINFO=y +CONFIG_CMDLINE_TAG=y +CONFIG_SETUP_MEMORY_TAGS=y +# CONFIG_INITRD_TAG is not set +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_GREGORIAN_CALENDER=y +CONFIG_HAS_KALLSYMS=y +CONFIG_HAS_MODULES=y +CONFIG_CMD_MEMORY=y +CONFIG_ENV_HANDLING=y +CONFIG_GENERIC_GPIO=y + +# +# General Settings +# +CONFIG_LOCALVERSION_AUTO=y + +# +# memory layout +# +CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y +CONFIG_TEXT_BASE=0x05700000 +CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y +CONFIG_MEMORY_LAYOUT_DEFAULT=y +# CONFIG_MEMORY_LAYOUT_FIXED is not set +CONFIG_STACK_SIZE=0x8000 +CONFIG_MALLOC_SIZE=0x400000 +# CONFIG_BROKEN is not set +# CONFIG_EXPERIMENTAL is not set +CONFIG_MACH_HAS_LOWLEVEL_INIT=y +CONFIG_MACH_DO_LOWLEVEL_INIT=y +CONFIG_PROMPT="barebox:" +CONFIG_BAUDRATE=115200 +CONFIG_LONGHELP=y +CONFIG_CBSIZE=1024 +CONFIG_MAXARGS=16 +CONFIG_SHELL_HUSH=y +# CONFIG_SHELL_SIMPLE is not set +CONFIG_GLOB=y +CONFIG_PROMPT_HUSH_PS2="> " +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_DYNAMIC_CRC_TABLE=y +CONFIG_ERRNO_MESSAGES=y +CONFIG_TIMESTAMP=y +CONFIG_CONSOLE_FULL=y +CONFIG_CONSOLE_ACTIVATE_FIRST=y +# CONFIG_OF_FLAT_TREE is not set +CONFIG_PARTITION=y +CONFIG_DEFAULT_ENVIRONMENT=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="board/edb93xx/env" + +# +# Debugging +# +# CONFIG_DEBUG_INFO is not set +# CONFIG_ENABLE_FLASH_NOISE is not set +# CONFIG_ENABLE_PARTITION_NOISE is not set +# CONFIG_ENABLE_DEVICE_NOISE is not set + +# +# Commands +# + +# +# scripting +# +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TRUE=y +CONFIG_CMD_FALSE=y + +# +# file commands +# +CONFIG_CMD_LS=y +CONFIG_CMD_RM=y +CONFIG_CMD_CAT=y +CONFIG_CMD_MKDIR=y +CONFIG_CMD_RMDIR=y +CONFIG_CMD_CP=y +CONFIG_CMD_PWD=y +CONFIG_CMD_CD=y +CONFIG_CMD_MOUNT=y +CONFIG_CMD_UMOUNT=y + +# +# console +# +CONFIG_CMD_CLEAR=y +CONFIG_CMD_ECHO=y + +# +# memory +# +# CONFIG_CMD_LOADB is not set +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_CRC=y +CONFIG_CMD_MTEST=y +# CONFIG_CMD_MTEST_ALTERNATIVE is not set + +# +# flash +# +CONFIG_CMD_FLASH=y + +# +# booting +# +CONFIG_CMD_BOOTM=y +# CONFIG_CMD_BOOTM_ZLIB is not set +# CONFIG_CMD_BOOTM_BZLIB is not set +# CONFIG_CMD_BOOTM_SHOW_TYPE is not set +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_BOOTU=y +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_TEST=y +CONFIG_CMD_VERSION=y +CONFIG_CMD_HELP=y +CONFIG_CMD_DEVINFO=y +CONFIG_CMD_GPIO=y +CONFIG_NET=y +CONFIG_NET_DHCP=y +# CONFIG_NET_RARP is not set +# CONFIG_NET_NFS is not set +CONFIG_NET_PING=y +CONFIG_NET_TFTP=y + +# +# Drivers +# + +# +# serial drivers +# +# CONFIG_DRIVER_SERIAL_ARM_DCC is not set +# CONFIG_DRIVER_SERIAL_NS16550 is not set +CONFIG_DRIVER_SERIAL_PL010=y +CONFIG_MIIPHY=y + +# +# Network drivers +# +# CONFIG_DRIVER_NET_SMC911X is not set +# CONFIG_DRIVER_NET_SMC91111 is not set +CONFIG_DRIVER_NET_EP93XX=y + +# +# SPI drivers +# +# CONFIG_SPI is not set +# CONFIG_I2C is not set + +# +# flash drivers +# +CONFIG_DRIVER_CFI=y +# CONFIG_DRIVER_CFI_NEW is not set +CONFIG_DRIVER_CFI_OLD=y +# CONFIG_CFI_BUFFER_WRITE is not set +# CONFIG_NAND is not set +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set +# CONFIG_VIDEO is not set + +# +# Filesystem support +# +# CONFIG_FS_CRAMFS is not set +CONFIG_FS_RAMFS=y +CONFIG_FS_DEVFS=y +CONFIG_CRC32=y +# CONFIG_GENERIC_FIND_NEXT_BIT is not set diff --git a/arch/arm/configs/freescale_mx35_3stack_defconfig b/arch/arm/configs/freescale_mx35_3stack_defconfig index 1319a695e6..17a2fdc6d9 100644 --- a/arch/arm/configs/freescale_mx35_3stack_defconfig +++ b/arch/arm/configs/freescale_mx35_3stack_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# barebox version: 2.0.0-rc10 -# Fri Dec 18 11:47:45 2009 +# barebox version: 2009.12.0-pre +# Tue Dec 22 17:43:43 2009 # # CONFIG_BOARD_LINKER_SCRIPT is not set CONFIG_GENERIC_LINKER_SCRIPT=y @@ -43,17 +43,17 @@ CONFIG_MACH_FREESCALE_MX35_3STACK=y # CONFIG_MACH_PCM043 is not set # -# Board specific settings +# Board specific settings # # -# i.MX specific settings +# i.MX specific settings # # CONFIG_IMX_CLKO is not set -# CONFIG_AEABI is not set +CONFIG_AEABI=y # -# Arm specific settings +# Arm specific settings # CONFIG_CMD_ARM_CPUINFO=y CONFIG_CMDLINE_TAG=y @@ -68,12 +68,12 @@ CONFIG_ENV_HANDLING=y CONFIG_GENERIC_GPIO=y # -# General Settings +# General Settings # CONFIG_LOCALVERSION_AUTO=y # -# memory layout +# memory layout # CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y CONFIG_TEXT_BASE=0x87F00000 @@ -81,7 +81,7 @@ CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y CONFIG_MEMORY_LAYOUT_DEFAULT=y # CONFIG_MEMORY_LAYOUT_FIXED is not set CONFIG_STACK_SIZE=0x8000 -CONFIG_MALLOC_SIZE=0x400000 +CONFIG_MALLOC_SIZE=0x1000000 # CONFIG_BROKEN is not set # CONFIG_EXPERIMENTAL is not set CONFIG_MACH_HAS_LOWLEVEL_INIT=y @@ -105,10 +105,10 @@ CONFIG_CONSOLE_ACTIVATE_FIRST=y # CONFIG_OF_FLAT_TREE is not set CONFIG_PARTITION=y CONFIG_DEFAULT_ENVIRONMENT=y -CONFIG_DEFAULT_ENVIRONMENT_PATH="board/pcm043/env/" +CONFIG_DEFAULT_ENVIRONMENT_PATH="board/freescale-mx35-3-stack/env/" # -# Debugging +# Debugging # # CONFIG_DEBUG_INFO is not set # CONFIG_ENABLE_FLASH_NOISE is not set @@ -116,11 +116,11 @@ CONFIG_DEFAULT_ENVIRONMENT_PATH="board/pcm043/env/" # CONFIG_ENABLE_DEVICE_NOISE is not set # -# Commands +# Commands # # -# scripting +# scripting # CONFIG_CMD_EDIT=y CONFIG_CMD_SLEEP=y @@ -133,7 +133,7 @@ CONFIG_CMD_TRUE=y CONFIG_CMD_FALSE=y # -# file commands +# file commands # CONFIG_CMD_LS=y CONFIG_CMD_RM=y @@ -147,13 +147,13 @@ CONFIG_CMD_MOUNT=y CONFIG_CMD_UMOUNT=y # -# console +# console # CONFIG_CMD_CLEAR=y CONFIG_CMD_ECHO=y # -# memory +# memory # # CONFIG_CMD_LOADB is not set CONFIG_CMD_MEMINFO=y @@ -161,12 +161,12 @@ CONFIG_CMD_CRC=y # CONFIG_CMD_MTEST is not set # -# flash +# flash # CONFIG_CMD_FLASH=y # -# booting +# booting # CONFIG_CMD_BOOTM=y # CONFIG_CMD_BOOTM_ZLIB is not set @@ -182,7 +182,8 @@ CONFIG_CMD_TEST=y CONFIG_CMD_VERSION=y CONFIG_CMD_HELP=y CONFIG_CMD_DEVINFO=y -CONFIG_CMD_GPIO=y +CONFIG_CMD_BMP=y +# CONFIG_CMD_GPIO is not set CONFIG_NET=y CONFIG_NET_DHCP=y # CONFIG_NET_RARP is not set @@ -191,11 +192,11 @@ CONFIG_NET_PING=y CONFIG_NET_TFTP=y # -# Drivers +# Drivers # # -# serial drivers +# serial drivers # # CONFIG_DRIVER_SERIAL_ARM_DCC is not set CONFIG_DRIVER_SERIAL_IMX=y @@ -203,39 +204,43 @@ CONFIG_DRIVER_SERIAL_IMX=y CONFIG_MIIPHY=y # -# Network drivers +# Network drivers # CONFIG_DRIVER_NET_SMC911X=y CONFIG_DRIVER_NET_SMC911X_ADDRESS_SHIFT=0 # CONFIG_DRIVER_NET_SMC91111 is not set -# CONFIG_DRIVER_NET_FEC_IMX is not set +CONFIG_DRIVER_NET_FEC_IMX=y # -# SPI drivers +# SPI drivers # -CONFIG_SPI=y -# CONFIG_DRIVER_SPI_IMX is not set -# CONFIG_DRIVER_SPI_MC13783 is not set +# CONFIG_SPI is not set CONFIG_I2C=y CONFIG_DRIVER_I2C_IMX=y CONFIG_DRIVER_I2C_MC13892=y CONFIG_DRIVER_I2C_MC9SDZ60=y # -# flash drivers +# flash drivers # CONFIG_HAS_CFI=y CONFIG_DRIVER_CFI=y # CONFIG_DRIVER_CFI_NEW is not set CONFIG_DRIVER_CFI_OLD=y CONFIG_CFI_BUFFER_WRITE=y -# CONFIG_NAND is not set +CONFIG_NAND=y +CONFIG_NAND_IMX=y +CONFIG_NAND_IMX_BOOT=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=y # CONFIG_USB is not set # CONFIG_USB_GADGET is not set -# CONFIG_VIDEO is not set +CONFIG_VIDEO=y +CONFIG_DRIVER_VIDEO_IMX_IPU=y # -# Filesystem support +# Filesystem support # # CONFIG_FS_CRAMFS is not set CONFIG_FS_RAMFS=y diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S index c8d1bb9d85..a5eaefa213 100644 --- a/arch/arm/lib/barebox.lds.S +++ b/arch/arm/lib/barebox.lds.S @@ -39,6 +39,11 @@ SECTIONS _stext = .; _text = .; *(.text_entry*) +#ifdef CONFIG_ARCH_EP93XX + /* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */ + . = 0x1000; + LONG(0x53555243) /* 'CRUS' */ +#endif *(.text_bare_init*) *(.text*) } diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig new file mode 100644 index 0000000000..ed6e9864c7 --- /dev/null +++ b/arch/arm/mach-ep93xx/Kconfig @@ -0,0 +1,438 @@ +if ARCH_EP93XX + +config EP93XX_SDCE0_PHYS_OFFSET + bool + +config EP93XX_SDCE3_SYNC_PHYS_OFFSET + bool + +comment "Cirrus EP93xx System-on-Chip" + +choice + prompt "Cirrus Logic EP93XX Processor" + +config ARCH_EP9301 + bool "EP9301" + +config ARCH_EP9302 + bool "EP9302" + +config ARCH_EP9307 + bool "EP9307" + +config ARCH_EP9312 + bool "EP9312" + +config ARCH_EP9315 + bool "EP9315" + +endchoice + +# ---------------------------------------------------------- + +if ARCH_EP9301 + +choice + prompt "EP9301 Board Type" + +config MACH_EDB9301 + bool "Cirrus Logic EDB9301" + select EP93XX_SDCE3_SYNC_PHYS_OFFSET + select MACH_HAS_LOWLEVEL_INIT + help + Say y here if you are using Cirrus Logic's EDB9301 Evaluation board + +endchoice + +if MACH_EDB9301 + +config BOARDINFO + default "Cirrus Logic EDB9301" + +config ARCH_TEXT_BASE + hex + default 0x05700000 + +config EP93XX_SDRAM_NUM_BANKS + int + default 4 + +config EP93XX_SDRAM_BANK0_BASE + hex + default 0x00000000 + +config EP93XX_SDRAM_BANK0_SIZE + hex + default 0x00800000 + +config EP93XX_SDRAM_BANK1_BASE + hex + default 0x01000000 + +config EP93XX_SDRAM_BANK1_SIZE + hex + default 0x00800000 + +config EP93XX_SDRAM_BANK2_BASE + hex + default 0x04000000 + +config EP93XX_SDRAM_BANK2_SIZE + hex + default 0x00800000 + +config EP93XX_SDRAM_BANK3_BASE + hex + default 0x05000000 + +config EP93XX_SDRAM_BANK3_SIZE + hex + default 0x00800000 + +endif + +endif + +# ---------------------------------------------------------- + +if ARCH_EP9302 + +choice + prompt "EP9302 Board Type" + +config MACH_EDB9302 + bool "Cirrus Logic EDB9302" + select EP93XX_SDCE3_SYNC_PHYS_OFFSET + select MACH_HAS_LOWLEVEL_INIT + help + Say y here if you are using Cirrus Logic's EDB9302 Evaluation board + +config MACH_EDB9302A + bool "Cirrus Logic EDB9302A" + select EP93XX_SDCE0_PHYS_OFFSET + select MACH_HAS_LOWLEVEL_INIT + help + Say y here if you are using Cirrus Logic's EDB9302A Evaluation board + +endchoice + +if MACH_EDB9302 + +config BOARDINFO + default "Cirrus Logic EDB9302" + +config ARCH_TEXT_BASE + hex + default 0x05700000 + +config EP93XX_SDRAM_NUM_BANKS + int + default 4 + +config EP93XX_SDRAM_BANK0_BASE + hex + default 0x00000000 + +config EP93XX_SDRAM_BANK0_SIZE + hex + default 0x00800000 + +config EP93XX_SDRAM_BANK1_BASE + hex + default 0x01000000 + +config EP93XX_SDRAM_BANK1_SIZE + hex + default 0x00800000 + +config EP93XX_SDRAM_BANK2_BASE + hex + default 0x04000000 + +config EP93XX_SDRAM_BANK2_SIZE + hex + default 0x00800000 + +config EP93XX_SDRAM_BANK3_BASE + hex + default 0x05000000 + +config EP93XX_SDRAM_BANK3_SIZE + hex + default 0x00800000 + +endif + +if MACH_EDB9302A + +config BOARDINFO + default "Cirrus Logic EDB9302A" + +config ARCH_TEXT_BASE + hex + default 0xc5700000 + +config EP93XX_SDRAM_NUM_BANKS + int + default 4 + +config EP93XX_SDRAM_BANK0_BASE + hex + default 0xc0000000 + +config EP93XX_SDRAM_BANK0_SIZE + hex + default 0x00800000 + +config EP93XX_SDRAM_BANK1_BASE + hex + default 0xc1000000 + +config EP93XX_SDRAM_BANK1_SIZE + hex + default 0x00800000 + +config EP93XX_SDRAM_BANK2_BASE + hex + default 0xc4000000 + +config EP93XX_SDRAM_BANK2_SIZE + hex + default 0x00800000 + +config EP93XX_SDRAM_BANK3_BASE + hex + default 0xc5000000 + +config EP93XX_SDRAM_BANK3_SIZE + hex + default 0x00800000 + +endif + +endif + +# ---------------------------------------------------------- + +if ARCH_EP9307 + +choice + prompt "EP9307 Board Type" + +config MACH_EDB9307 + bool "Cirrus Logic EDB9307" + select EP93XX_SDCE3_SYNC_PHYS_OFFSET + select MACH_HAS_LOWLEVEL_INIT + help + Say y here if you are using Cirrus Logic's EDB9307 Evaluation board + +config MACH_EDB9307A + bool "Cirrus Logic EDB9307A" + select EP93XX_SDCE0_PHYS_OFFSET + select MACH_HAS_LOWLEVEL_INIT + help + Say y here if you are using Cirrus Logic's EDB9307A Evaluation board + +endchoice + +if MACH_EDB9307 + +config BOARDINFO + default "Cirrus Logic EDB9307" + +config ARCH_TEXT_BASE + hex + default 0x01f00000 + +config EP93XX_SDRAM_NUM_BANKS + int + default 2 + +config EP93XX_SDRAM_BANK0_BASE + hex + default 0x00000000 + +config EP93XX_SDRAM_BANK0_SIZE + hex + default 0x02000000 + +config EP93XX_SDRAM_BANK1_BASE + hex + default 0x04000000 + +config EP93XX_SDRAM_BANK1_SIZE + hex + default 0x02000000 + +endif + +if MACH_EDB9307A + +config BOARDINFO + default "Cirrus Logic EDB9307A" + +config ARCH_TEXT_BASE + hex + default 0xc1f00000 + +config EP93XX_SDRAM_NUM_BANKS + int + default 2 + +config EP93XX_SDRAM_BANK0_BASE + hex + default 0xc0000000 + +config EP93XX_SDRAM_BANK0_SIZE + hex + default 0x02000000 + +config EP93XX_SDRAM_BANK1_BASE + hex + default 0xc4000000 + +config EP93XX_SDRAM_BANK1_SIZE + hex + default 0x02000000 + +endif + +endif + +# ---------------------------------------------------------- + +if ARCH_EP9312 + +choice + prompt "EP9312 Board Type" + +config MACH_EDB9312 + bool "Cirrus Logic EDB9312" + select EP93XX_SDCE3_SYNC_PHYS_OFFSET + select MACH_HAS_LOWLEVEL_INIT + help + Say y here if you are using Cirrus Logic's EDB9312 Evaluation board + +endchoice + +if MACH_EDB9312 + +config BOARDINFO + default "Cirrus Logic EDB9312" + +config ARCH_TEXT_BASE + hex + default 0x01f00000 + +config EP93XX_SDRAM_NUM_BANKS + int + default 2 + +config EP93XX_SDRAM_BANK0_BASE + hex + default 0x00000000 + +config EP93XX_SDRAM_BANK0_SIZE + hex + default 0x02000000 + +config EP93XX_SDRAM_BANK1_BASE + hex + default 0x04000000 + +config EP93XX_SDRAM_BANK1_SIZE + hex + default 0x02000000 + +endif + +endif + +# ---------------------------------------------------------- + +if ARCH_EP9315 + +choice + prompt "EP9315 Board Type" + +config MACH_EDB9315 + bool "Cirrus Logic EDB9315" + select EP93XX_SDCE3_SYNC_PHYS_OFFSET + select MACH_HAS_LOWLEVEL_INIT + help + Say y here if you are using Cirrus Logic's EDB9315 Evaluation board + +config MACH_EDB9315A + bool "Cirrus Logic EDB9315A" + select EP93XX_SDCE0_PHYS_OFFSET + select MACH_HAS_LOWLEVEL_INIT + help + Say y here if you are using Cirrus Logic's EDB9315A Evaluation board + +endchoice + +if MACH_EDB9315 + +config BOARDINFO + default "Cirrus Logic EDB9315" + +config ARCH_TEXT_BASE + hex + default 0x01f00000 + +config EP93XX_SDRAM_NUM_BANKS + int + default 2 + +config EP93XX_SDRAM_BANK0_BASE + hex + default 0x00000000 + +config EP93XX_SDRAM_BANK0_SIZE + hex + default 0x02000000 + +config EP93XX_SDRAM_BANK1_BASE + hex + default 0x04000000 + +config EP93XX_SDRAM_BANK1_SIZE + hex + default 0x02000000 + +endif + +if MACH_EDB9315A + +config BOARDINFO + default "Cirrus Logic EDB9315A" + +config ARCH_TEXT_BASE + hex + default 0xc1f00000 + +config EP93XX_SDRAM_NUM_BANKS + int + default 2 + +config EP93XX_SDRAM_BANK0_BASE + hex + default 0xc0000000 + +config EP93XX_SDRAM_BANK0_SIZE + hex + default 0x02000000 + +config EP93XX_SDRAM_BANK1_BASE + hex + default 0xc4000000 + +config EP93XX_SDRAM_BANK1_SIZE + hex + default 0x02000000 + +endif + +endif + +endif diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile new file mode 100644 index 0000000000..dac657178a --- /dev/null +++ b/arch/arm/mach-ep93xx/Makefile @@ -0,0 +1,3 @@ +obj-y += clocksource.o gpio.o led.o + +obj-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o diff --git a/arch/arm/mach-ep93xx/clocksource.c b/arch/arm/mach-ep93xx/clocksource.c new file mode 100644 index 0000000000..2a7d90e4e2 --- /dev/null +++ b/arch/arm/mach-ep93xx/clocksource.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <init.h> +#include <clock.h> +#include <asm/io.h> +#include <mach/ep93xx-regs.h> + +#define TIMER_CLKSEL (1 << 3) +#define TIMER_MODE (1 << 6) +#define TIMER_ENABLE (1 << 7) + +#define TIMER_FREQ 508469 + +static uint64_t ep93xx_clocksource_read(void) +{ + struct timer_regs *timer = (struct timer_regs *)TIMER_BASE; + + return 0xffffffff - readl(&timer->timer3.value); +} + +static struct clocksource cs = { + .read = ep93xx_clocksource_read, + .mask = 0xffffffff, + .shift = 10, +}; + +static int clocksource_init(void) +{ + struct timer_regs *timer = (struct timer_regs *)TIMER_BASE; + + /* use timer 3 with 508KHz and free running */ + writel(TIMER_CLKSEL, + &timer->timer3.control); + + /* load timer 3 with max value */ + writel(0xffffffff, &timer->timer3.load); + + /* enable timer 3 with 508KHz and periodic mode */ + writel(TIMER_ENABLE | TIMER_MODE | TIMER_CLKSEL, + &timer->timer3.control); + + cs.mult = clocksource_hz2mult(TIMER_FREQ, cs.shift); + + init_clock(&cs); + + return 0; +} + +core_initcall(clocksource_init); + +/* + * Reset the cpu + */ +void reset_cpu(ulong ignored) +{ + struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + uint32_t value; + + /* Unlock DeviceCfg and set SWRST */ + writel(0xAA, &syscon->sysswlock); + value = readl(&syscon->devicecfg); + value |= SYSCON_DEVICECFG_SWRST; + writel(value, &syscon->devicecfg); + + /* Unlock DeviceCfg and clear SWRST */ + writel(0xAA, &syscon->sysswlock); + value = readl(&syscon->devicecfg); + value &= ~SYSCON_DEVICECFG_SWRST; + writel(value, &syscon->devicecfg); + + /* Dying... */ + while (1) + ; /* noop */ +} +EXPORT_SYMBOL(reset_cpu); diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c new file mode 100644 index 0000000000..5d57434031 --- /dev/null +++ b/arch/arm/mach-ep93xx/gpio.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2010 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <common.h> +#include <errno.h> +#include <init.h> +#include <asm/io.h> +#include <mach/ep93xx-regs.h> + +#define EP93XX_GPIO_NUM_PORTS 8 +#define EP93XX_GPIO_NUM_GPIOS (EP93XX_GPIO_NUM_PORTS * 8) + +struct gpio_port { + uint32_t *dr; + uint32_t *ddr; +}; + +struct gpio_port gpio_ports[EP93XX_GPIO_NUM_PORTS]; + +static int ep93xx_gpio_init(void) +{ + struct gpio_regs *gpio_regs = (struct gpio_regs *)GPIO_BASE; + + gpio_ports[0].dr = &gpio_regs->padr; + gpio_ports[0].ddr = &gpio_regs->paddr; + gpio_ports[1].dr = &gpio_regs->pbdr; + gpio_ports[1].ddr = &gpio_regs->pbddr; + gpio_ports[2].dr = &gpio_regs->pcdr; + gpio_ports[2].ddr = &gpio_regs->pcddr; + gpio_ports[3].dr = &gpio_regs->pddr; + gpio_ports[3].ddr = &gpio_regs->pdddr; + gpio_ports[4].dr = &gpio_regs->pedr; + gpio_ports[4].ddr = &gpio_regs->peddr; + gpio_ports[5].dr = &gpio_regs->pfdr; + gpio_ports[5].ddr = &gpio_regs->pfddr; + gpio_ports[6].dr = &gpio_regs->pgdr; + gpio_ports[6].ddr = &gpio_regs->pgddr; + gpio_ports[7].dr = &gpio_regs->phdr; + gpio_ports[7].ddr = &gpio_regs->phddr; + + return 0; +} + +postcore_initcall(ep93xx_gpio_init); + +static struct gpio_port *gpio_get_port(unsigned gpio) +{ + if (gpio >= EP93XX_GPIO_NUM_GPIOS) + return 0; + + return &gpio_ports[gpio / 8]; +} + +void gpio_set_value(unsigned gpio, int value) +{ + struct gpio_port *port = gpio_get_port(gpio); + const int shift = gpio % 8; + u32 val; + + if (!port) + return; + + val = readl(port->dr); + + if (value) + val |= 1 << shift; + else + val &= ~(1 << shift); + + writel(val, port->dr); +} + +int gpio_direction_input(unsigned gpio) +{ + struct gpio_port *port = gpio_get_port(gpio); + const int shift = gpio % 8; + u32 val; + + if (!port) + return -EINVAL; + + val = readl(port->ddr); + val &= ~(1 << shift); + writel(val, port->ddr); + + return 0; +} + +int gpio_direction_output(unsigned gpio, int value) +{ + struct gpio_port *port = gpio_get_port(gpio); + const int shift = gpio % 8; + u32 val; + + if (!port) + return -EINVAL; + + gpio_set_value(gpio, value); + + val = readl(port->ddr); + val |= 1 << shift; + writel(val, port->ddr); + + return 0; +} + +int gpio_get_value(unsigned gpio) +{ + struct gpio_port *port = gpio_get_port(gpio); + const int shift = gpio % 8; + u32 val; + + if (!port) + return -EINVAL; + + val = readl(port->dr); + + return val & (1 << shift) ? 1 : 0; +} + diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h new file mode 100644 index 0000000000..50bb0eb41f --- /dev/null +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h @@ -0,0 +1,600 @@ +/* ----------------------------------------------------------------------------- + * Cirrus Logic EP93xx register definitions. + * + * Copyright (C) 2009 + * Matthias Kaehlcke <matthias@kaehlcke.net> + * + * Copyright (C) 2006 + * Dominic Rath <Dominic.Rath@gmx.de> + * + * Copyright (C) 2004, 2005 + * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com> + * + * Based in large part on linux/include/asm-arm/arch-ep93xx/regmap.h, which is + * + * Copyright (C) 2004 Ray Lehtiniemi + * Copyright (C) 2003 Cirrus Logic, Inc + * Copyright (C) 1999 ARM Limited. + * + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ASSEMBLY__ +#include <linux/types.h> +#endif + +#define EP93XX_AHB_BASE 0x80000000 +#define EP93XX_APB_BASE 0x80800000 + +/* ----------------------------------------------------------------------------- + * 0x80000000 - 0x8000FFFF: DMA + */ +#define DMA_OFFSET 0x000000 +#define DMA_BASE (EP93XX_AHB_BASE | DMA_OFFSET) + +#ifndef __ASSEMBLY__ +struct dma_channel { + uint32_t control; + uint32_t interrupt; + uint32_t ppalloc; + uint32_t status; + uint32_t reserved0; + uint32_t remain; + uint32_t reserved1[2]; + uint32_t maxcnt0; + uint32_t base0; + uint32_t current0; + uint32_t reserved2; + uint32_t maxcnt1; + uint32_t base1; + uint32_t current1; + uint32_t reserved3; +}; + +struct dma_regs { + struct dma_channel m2p_channel_0; + struct dma_channel m2p_channel_1; + struct dma_channel m2p_channel_2; + struct dma_channel m2p_channel_3; + struct dma_channel m2m_channel_0; + struct dma_channel m2m_channel_1; + struct dma_channel reserved0[2]; + struct dma_channel m2p_channel_5; + struct dma_channel m2p_channel_4; + struct dma_channel m2p_channel_7; + struct dma_channel m2p_channel_6; + struct dma_channel m2p_channel_9; + struct dma_channel m2p_channel_8; + uint32_t channel_arbitration; + uint32_t reserved[15]; + uint32_t global_interrupt; +}; +#endif + +/* ----------------------------------------------------------------------------- + * 0x80010000 - 0x8001FFFF: Ethernet MAC + */ +#define MAC_OFFSET 0x010000 +#define MAC_BASE (EP93XX_AHB_BASE | MAC_OFFSET) + +#ifndef __ASSEMBLY__ +struct mac_queue { + uint32_t badd; + union { /* deal with half-word aligned registers */ + uint32_t blen; + union { + uint16_t filler; + uint16_t curlen; + }; + }; + uint32_t curadd; +}; + +struct mac_regs { + uint32_t rxctl; + uint32_t txctl; + uint32_t testctl; + uint32_t reserved0; + uint32_t miicmd; + uint32_t miidata; + uint32_t miists; + uint32_t reserved1; + uint32_t selfctl; + uint32_t inten; + uint32_t intstsp; + uint32_t intstsc; + uint32_t reserved2[2]; + uint32_t diagad; + uint32_t diagdata; + uint32_t gt; + uint32_t fct; + uint32_t fcf; + uint32_t afp; + union { + struct { + uint32_t indad; + uint32_t indad_upper; + }; + uint32_t hashtbl; + }; + uint32_t reserved3[2]; + uint32_t giintsts; + uint32_t giintmsk; + uint32_t giintrosts; + uint32_t giintfrc; + uint32_t txcollcnt; + uint32_t rxmissnct; + uint32_t rxruntcnt; + uint32_t reserved4; + uint32_t bmctl; + uint32_t bmsts; + uint32_t rxbca; + uint32_t reserved5; + struct mac_queue rxdq; + uint32_t rxdqenq; + struct mac_queue rxstsq; + uint32_t rxstsqenq; + struct mac_queue txdq; + uint32_t txdqenq; + struct mac_queue txstsq; + uint32_t reserved6; + uint32_t rxbufthrshld; + uint32_t txbufthrshld; + uint32_t rxststhrshld; + uint32_t txststhrshld; + uint32_t rxdthrshld; + uint32_t txdthrshld; + uint32_t maxfrmlen; + uint32_t maxhdrlen; +}; +#endif + +#define SELFCTL_RWP (1 << 7) +#define SELFCTL_GPO0 (1 << 5) +#define SELFCTL_PUWE (1 << 4) +#define SELFCTL_PDWE (1 << 3) +#define SELFCTL_MIIL (1 << 2) +#define SELFCTL_RESET (1 << 0) + +#define INTSTS_RWI (1 << 30) +#define INTSTS_RXMI (1 << 29) +#define INTSTS_RXBI (1 << 28) +#define INTSTS_RXSQI (1 << 27) +#define INTSTS_TXLEI (1 << 26) +#define INTSTS_ECIE (1 << 25) +#define INTSTS_TXUHI (1 << 24) +#define INTSTS_MOI (1 << 18) +#define INTSTS_TXCOI (1 << 17) +#define INTSTS_RXROI (1 << 16) +#define INTSTS_MIII (1 << 12) +#define INTSTS_PHYI (1 << 11) +#define INTSTS_TI (1 << 10) +#define INTSTS_AHBE (1 << 8) +#define INTSTS_OTHER (1 << 4) +#define INTSTS_TXSQ (1 << 3) +#define INTSTS_RXSQ (1 << 2) + +#define BMCTL_MT (1 << 13) +#define BMCTL_TT (1 << 12) +#define BMCTL_UNH (1 << 11) +#define BMCTL_TXCHR (1 << 10) +#define BMCTL_TXDIS (1 << 9) +#define BMCTL_TXEN (1 << 8) +#define BMCTL_EH2 (1 << 6) +#define BMCTL_EH1 (1 << 5) +#define BMCTL_EEOB (1 << 4) +#define BMCTL_RXCHR (1 << 2) +#define BMCTL_RXDIS (1 << 1) +#define BMCTL_RXEN (1 << 0) + +#define BMSTS_TXACT (1 << 7) +#define BMSTS_TP (1 << 4) +#define BMSTS_RXACT (1 << 3) +#define BMSTS_QID_MASK 0x07 +#define BMSTS_QID_RXDATA 0x00 +#define BMSTS_QID_TXDATA 0x01 +#define BMSTS_QID_RXSTS 0x02 +#define BMSTS_QID_TXSTS 0x03 +#define BMSTS_QID_RXDESC 0x04 +#define BMSTS_QID_TXDESC 0x05 + +#define AFP_MASK 0x07 +#define AFP_IAPRIMARY 0x00 +#define AFP_IASECONDARY1 0x01 +#define AFP_IASECONDARY2 0x02 +#define AFP_IASECONDARY3 0x03 +#define AFP_TX 0x06 +#define AFP_HASH 0x07 + +#define RXCTL_PAUSEA (1 << 20) +#define RXCTL_RXFCE1 (1 << 19) +#define RXCTL_RXFCE0 (1 << 18) +#define RXCTL_BCRC (1 << 17) +#define RXCTL_SRXON (1 << 16) +#define RXCTL_RCRCA (1 << 13) +#define RXCTL_RA (1 << 12) +#define RXCTL_PA (1 << 11) +#define RXCTL_BA (1 << 10) +#define RXCTL_MA (1 << 9) +#define RXCTL_IAHA (1 << 8) +#define RXCTL_IA3 (1 << 3) +#define RXCTL_IA2 (1 << 2) +#define RXCTL_IA1 (1 << 1) +#define RXCTL_IA0 (1 << 0) + +#define TXCTL_DEFDIS (1 << 7) +#define TXCTL_MBE (1 << 6) +#define TXCTL_ICRC (1 << 5) +#define TXCTL_TPD (1 << 4) +#define TXCTL_OCOLL (1 << 3) +#define TXCTL_SP (1 << 2) +#define TXCTL_PB (1 << 1) +#define TXCTL_STXON (1 << 0) + +#define MIICMD_REGAD_MASK (0x001F) +#define MIICMD_PHYAD_MASK (0x03E0) +#define MIICMD_OPCODE_MASK (0xC000) +#define MIICMD_PHYAD_8950 (0x0000) +#define MIICMD_OPCODE_READ (0x8000) +#define MIICMD_OPCODE_WRITE (0x4000) + +#define MIISTS_BUSY (1 << 0) + +/* ----------------------------------------------------------------------------- + * 0x80020000 - 0x8002FFFF: USB OHCI + */ +#define USB_OFFSET 0x020000 +#define USB_BASE (EP93XX_AHB_BASE | USB_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x80030000 - 0x8003FFFF: Raster engine + */ +#if (defined(CONFIG_EP9307) || defined(CONFIG_EP9312) || defined(CONFIG_EP9315)) +#define RASTER_OFFSET 0x030000 +#define RASTER_BASE (EP93XX_AHB_BASE | RASTER_OFFSET) +#endif + +/* ----------------------------------------------------------------------------- + * 0x80040000 - 0x8004FFFF: Graphics accelerator + */ +#if defined(CONFIG_EP9315) +#define GFX_OFFSET 0x040000 +#define GFX_BASE (EP93XX_AHB_BASE | GFX_OFFSET) +#endif + +/* ----------------------------------------------------------------------------- + * 0x80050000 - 0x8005FFFF: Reserved + */ + +/* ----------------------------------------------------------------------------- + * 0x80060000 - 0x8006FFFF: SDRAM controller + */ +#define SDRAM_OFFSET 0x060000 +#define SDRAM_BASE (EP93XX_AHB_BASE | SDRAM_OFFSET) + +#ifndef __ASSEMBLY__ +struct sdram_regs { + uint32_t reserved; + uint32_t glconfig; + uint32_t refrshtimr; + uint32_t bootsts; + uint32_t devcfg0; + uint32_t devcfg1; + uint32_t devcfg2; + uint32_t devcfg3; +}; +#endif + +#define SDRAM_DEVCFG_EXTBUSWIDTH (1 << 2) +#define SDRAM_DEVCFG_BANKCOUNT (1 << 3) +#define SDRAM_DEVCFG_SROMLL (1 << 5) +#define SDRAM_DEVCFG_CASLAT_2 0x00010000 +#define SDRAM_DEVCFG_RASTOCAS_2 0x00200000 + +#define GLCONFIG_INIT (1 << 0) +#define GLCONFIG_MRS (1 << 1) +#define GLCONFIG_SMEMBUSY (1 << 5) +#define GLCONFIG_LCR (1 << 6) +#define GLCONFIG_REARBEN (1 << 7) +#define GLCONFIG_CLKSHUTDOWN (1 << 30) +#define GLCONFIG_CKE (1 << 31) + +/* ----------------------------------------------------------------------------- + * 0x80070000 - 0x8007FFFF: Reserved + */ + +/* ----------------------------------------------------------------------------- + * 0x80080000 - 0x8008FFFF: SRAM controller & PCMCIA + */ +#define SMC_OFFSET 0x080000 +#define SMC_BASE (EP93XX_AHB_BASE | SMC_OFFSET) + +#ifndef __ASSEMBLY__ +struct smc_regs { + uint32_t bcr0; + uint32_t bcr1; + uint32_t bcr2; + uint32_t bcr3; + uint32_t reserved0[2]; + uint32_t bcr6; + uint32_t bcr7; +#if defined(CONFIG_EP9315) + uint32_t pcattribute; + uint32_t pccommon; + uint32_t pcio; + uint32_t reserved1[5]; + uint32_t pcmciactrl; +#endif +}; +#endif + +#define SMC_BCR_IDCY_SHIFT 0 +#define SMC_BCR_WST1_SHIFT 5 +#define SMC_BCR_BLE (1 << 10) +#define SMC_BCR_WST2_SHIFT 11 +#define SMC_BCR_MW_SHIFT 28 + +/* ----------------------------------------------------------------------------- + * 0x80090000 - 0x8009FFFF: Boot ROM + */ + +/* ----------------------------------------------------------------------------- + * 0x800A0000 - 0x800AFFFF: IDE interface + */ + +/* ----------------------------------------------------------------------------- + * 0x800B0000 - 0x800BFFFF: VIC1 + */ + +/* ----------------------------------------------------------------------------- + * 0x800C0000 - 0x800CFFFF: VIC2 + */ + +/* ----------------------------------------------------------------------------- + * 0x800D0000 - 0x800FFFFF: Reserved + */ + +/* ----------------------------------------------------------------------------- + * 0x80800000 - 0x8080FFFF: Reserved + */ + +/* ----------------------------------------------------------------------------- + * 0x80810000 - 0x8081FFFF: Timers + */ +#define TIMER_OFFSET 0x010000 +#define TIMER_BASE (EP93XX_APB_BASE | TIMER_OFFSET) + +#ifndef __ASSEMBLY__ +struct timer { + uint32_t load; + uint32_t value; + uint32_t control; + uint32_t clear; +}; + +struct timer4 { + uint32_t value_low; + uint32_t value_high; +}; + +struct timer_regs { + struct timer timer1; + uint32_t reserved0[4]; + struct timer timer2; + uint32_t reserved1[12]; + struct timer4 timer4; + uint32_t reserved2[6]; + struct timer timer3; +}; +#endif + +/* ----------------------------------------------------------------------------- + * 0x80820000 - 0x8082FFFF: I2S + */ +#define I2S_OFFSET 0x020000 +#define I2S_BASE (EP93XX_APB_BASE | I2S_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x80830000 - 0x8083FFFF: Security + */ +#define SECURITY_OFFSET 0x030000 +#define SECURITY_BASE (EP93XX_APB_BASE | SECURITY_OFFSET) + +#define EXTENSIONID (SECURITY_BASE + 0x2714) + +/* ----------------------------------------------------------------------------- + * 0x80840000 - 0x8084FFFF: GPIO + */ +#define GPIO_OFFSET 0x040000 +#define GPIO_BASE (EP93XX_APB_BASE | GPIO_OFFSET) + +#ifndef __ASSEMBLY__ +struct gpio_int { + uint32_t inttype1; + uint32_t inttype2; + uint32_t eoi; + uint32_t inten; + uint32_t intsts; + uint32_t rawintsts; + uint32_t db; +}; + +struct gpio_regs { + uint32_t padr; + uint32_t pbdr; + uint32_t pcdr; + uint32_t pddr; + uint32_t paddr; + uint32_t pbddr; + uint32_t pcddr; + uint32_t pdddr; + uint32_t pedr; + uint32_t peddr; + uint32_t reserved0[2]; + uint32_t pfdr; + uint32_t pfddr; + uint32_t pgdr; + uint32_t pgddr; + uint32_t phdr; + uint32_t phddr; + uint32_t reserved1; + uint32_t finttype1; + uint32_t finttype2; + uint32_t reserved2; + struct gpio_int pfint; + uint32_t reserved3[10]; + struct gpio_int paint; + struct gpio_int pbint; + uint32_t eedrive; +}; +#endif + +/* ----------------------------------------------------------------------------- + * 0x80850000 - 0x8087FFFF: Reserved + */ + +/* ----------------------------------------------------------------------------- + * 0x80880000 - 0x8088FFFF: AAC + */ +#define AAC_OFFSET 0x080000 +#define AAC_BASE (EP93XX_APB_BASE | AAC_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x80890000 - 0x8089FFFF: Reserved + */ + +/* ----------------------------------------------------------------------------- + * 0x808A0000 - 0x808AFFFF: SPI + */ +#define SPI_OFFSET 0x0A0000 +#define SPI_BASE (EP93XX_APB_BASE | SPI_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x808B0000 - 0x808BFFFF: IrDA + */ +#define IRDA_OFFSET 0x0B0000 +#define IRDA_BASE (EP93XX_APB_BASE | IRDA_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x808C0000 - 0x808CFFFF: UART1 + */ +#define UART1_OFFSET 0x0C0000 +#define UART1_BASE (EP93XX_APB_BASE | UART1_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x808D0000 - 0x808DFFFF: UART2 + */ +#define UART2_OFFSET 0x0D0000 +#define UART2_BASE (EP93XX_APB_BASE | UART2_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x808E0000 - 0x808EFFFF: UART3 + */ +#define UART3_OFFSET 0x0E0000 +#define UART3_BASE (EP93XX_APB_BASE | UART3_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x808F0000 - 0x808FFFFF: Key Matrix + */ +#define KEY_OFFSET 0x0F0000 +#define KEY_BASE (EP93XX_APB_BASE | KEY_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x80900000 - 0x8090FFFF: Touchscreen + */ +#define TOUCH_OFFSET 0x900000 +#define TOUCH_BASE (EP93XX_APB_BASE | TOUCH_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x80910000 - 0x8091FFFF: Pulse Width Modulation + */ +#define PWM_OFFSET 0x910000 +#define PWM_BASE (EP93XX_APB_BASE | PWM_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x80920000 - 0x8092FFFF: Real time clock + */ +#define RTC_OFFSET 0x920000 +#define RTC_BASE (EP93XX_APB_BASE | RTC_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x80930000 - 0x8093FFFF: Syscon + */ +#define SYSCON_OFFSET 0x930000 +#define SYSCON_BASE (EP93XX_APB_BASE | SYSCON_OFFSET) + +#ifndef __ASSEMBLY__ +struct syscon_regs { + uint32_t pwrsts; + uint32_t pwrcnt; + uint32_t halt; + uint32_t stby; + uint32_t reserved0[2]; + uint32_t teoi; + uint32_t stfclr; + uint32_t clkset1; + uint32_t clkset2; + uint32_t reserved1[6]; + uint32_t scratch0; + uint32_t scratch1; + uint32_t reserved2[2]; + uint32_t apbwait; + uint32_t bustmstrarb; + uint32_t bootmodeclr; + uint32_t reserved3[9]; + uint32_t devicecfg; + uint32_t vidclkdiv; + uint32_t mirclkdiv; + uint32_t i2sclkdiv; + uint32_t keytchclkdiv; + uint32_t chipid; + uint32_t syscfg; + uint32_t reserved4[8]; + uint32_t sysswlock; +}; +#else +#define SYSCON_SCRATCH0 (SYSCON_BASE + 0x0040) +#endif + +#define SYSCON_PWRCNT_UART_BAUD (1 << 29) + +#define SYSCON_CLKSET_PLL_X2IPD_SHIFT 0 +#define SYSCON_CLKSET_PLL_X2FBD2_SHIFT 5 +#define SYSCON_CLKSET_PLL_X1FBD1_SHIFT 11 +#define SYSCON_CLKSET_PLL_PS_SHIFT 16 +#define SYSCON_CLKSET1_PCLK_DIV_SHIFT 18 +#define SYSCON_CLKSET1_HCLK_DIV_SHIFT 20 +#define SYSCON_CLKSET1_NBYP1 (1 << 23) +#define SYSCON_CLKSET1_FCLK_DIV_SHIFT 25 + +#define SYSCON_CLKSET2_PLL2_EN (1 << 18) +#define SYSCON_CLKSET2_NBYP2 (1 << 19) +#define SYSCON_CLKSET2_USB_DIV_SHIFT 28 + +#define SYSCON_CHIPID_REV_MASK 0xF0000000 +#define SYSCON_DEVICECFG_SWRST (1 << 31) + +/* ----------------------------------------------------------------------------- + * 0x80930000 - 0x8093FFFF: Watchdog Timer + */ +#define WATCHDOG_OFFSET 0x940000 +#define WATCHDOG_BASE (EP93XX_APB_BASE | WATCHDOG_OFFSET) + +/* ----------------------------------------------------------------------------- + * 0x80950000 - 0x9000FFFF: Reserved + */ + diff --git a/arch/arm/mach-ep93xx/include/mach/gpio.h b/arch/arm/mach-ep93xx/include/mach/gpio.h new file mode 100644 index 0000000000..a305f274c4 --- /dev/null +++ b/arch/arm/mach-ep93xx/include/mach/gpio.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2010 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARCH_GPIO_H +#define __ASM_ARCH_GPIO_H + +void gpio_set_value(unsigned gpio, int value); +int gpio_get_value(unsigned gpio); +int gpio_direction_output(unsigned gpio, int value); +int gpio_direction_input(unsigned gpio); + +#endif /* __ASM_ARCH_GPIO_H */ + diff --git a/arch/arm/mach-ep93xx/led.c b/arch/arm/mach-ep93xx/led.c new file mode 100644 index 0000000000..6d6b90235f --- /dev/null +++ b/arch/arm/mach-ep93xx/led.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <mach/ep93xx-regs.h> + +#define GREEN_LED_POS 0x01 +#define RED_LED_POS 0x02 + +inline void switch_LED_on(uint32_t bit_pos) +{ + register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE; + + writel(readl(&gpio->pedr) | bit_pos, &gpio->pedr); +} + +inline void switch_LED_off(uint32_t bit_pos) +{ + register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE; + + writel(readl(&gpio->pedr) & ~bit_pos, &gpio->pedr); +} + +void red_LED_on(void) +{ + switch_LED_on(RED_LED_POS); +} + +void red_LED_off(void) +{ + switch_LED_off(RED_LED_POS); +} + +void green_LED_on(void) +{ + switch_LED_on(GREEN_LED_POS); +} + +void green_LED_off(void) +{ + switch_LED_off(GREEN_LED_POS); +} diff --git a/arch/arm/mach-ep93xx/led.h b/arch/arm/mach-ep93xx/led.h new file mode 100644 index 0000000000..db9512fc32 --- /dev/null +++ b/arch/arm/mach-ep93xx/led.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +extern void red_LED_on(void); +extern void red_LED_off(void); +extern void green_LED_on(void); +extern void green_LED_off(void); diff --git a/arch/arm/mach-ep93xx/lowlevel_init.S b/arch/arm/mach-ep93xx/lowlevel_init.S new file mode 100644 index 0000000000..27c2c90b7d --- /dev/null +++ b/arch/arm/mach-ep93xx/lowlevel_init.S @@ -0,0 +1,64 @@ +/* + * Low-level initialization for EP93xx + * + * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * Copyright (C) 2006 Dominic Rath <Dominic.Rath@gmx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <mach/ep93xx-regs.h> + +.globl board_init_lowlevel +board_init_lowlevel: + /* backup return address */ + ldr r1, =SYSCON_SCRATCH0 + str lr, [r1] + + /* Turn on both LEDs */ + bl red_LED_on + bl green_LED_on + + /* Configure flash wait states before we switch to the PLL */ + bl flash_cfg + + /* Set up PLL */ + bl pll_cfg + + /* Turn off the Green LED and leave the Red LED on */ + bl green_LED_off + + /* Setup SDRAM */ + bl sdram_cfg + + /* Turn on Green LED, Turn off the Red LED */ + bl green_LED_on + bl red_LED_off + + /* switch to async mode */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #0xc0000000 + mcr p15, 0, r0, c1, c0, 0 + + /* restore return address */ + ldr r1, =SYSCON_SCRATCH0 + ldr lr, [r1] + + mov pc, lr diff --git a/arch/arm/mach-imx/include/mach/imx27-regs.h b/arch/arm/mach-imx/include/mach/imx27-regs.h index 33d67d6f50..6c31ccd914 100644 --- a/arch/arm/mach-imx/include/mach/imx27-regs.h +++ b/arch/arm/mach-imx/include/mach/imx27-regs.h @@ -16,6 +16,7 @@ #define IMX_UART2_BASE (0x0b000 + IMX_IO_BASE) #define IMX_UART3_BASE (0x0c000 + IMX_IO_BASE) #define IMX_UART4_BASE (0x0d000 + IMX_IO_BASE) +#define IMX_I2C1_BASE (0x12000 + IMX_IO_BASE) #define IMX_GPIO_BASE (0x15000 + IMX_IO_BASE) #define IMX_TIM4_BASE (0x19000 + IMX_IO_BASE) #define IMX_TIM5_BASE (0x1a000 + IMX_IO_BASE) diff --git a/arch/arm/mach-imx/speed-imx27.c b/arch/arm/mach-imx/speed-imx27.c index deaca1eb4d..cdcd4191fe 100644 --- a/arch/arm/mach-imx/speed-imx27.c +++ b/arch/arm/mach-imx/speed-imx27.c @@ -154,6 +154,11 @@ ulong imx_get_lcdclk(void) return imx_get_perclk3(); } +ulong imx_get_i2cclk(void) +{ + return imx_get_ipgclk(); +} + void imx_dump_clocks(void) { uint32_t cid = CID; diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig new file mode 100644 index 0000000000..6e70760f58 --- /dev/null +++ b/arch/x86/Kconfig @@ -0,0 +1,67 @@ +# +# +# +config ARCH_TEXT_BASE + hex + default 0x00007c00 if MACH_X86_GENERIC + +config BOARDINFO + default "Generic x86 bootloader" if MACH_X86_GENERIC + +config BOARD_LINKER_SCRIPT + bool + default n + +config GENERIC_LINKER_SCRIPT + bool + default y + depends on !BOARD_LINKER_SCRIPT + +config X86 + bool + select HAS_KALLSYMS + select HAS_MODULES + select HAVE_CONFIGURABLE_MEMORY_LAYOUT + select HAVE_CONFIGURABLE_TEXT_BASE + default y + +choice + prompt "Select your board" + +config MACH_X86_GENERIC + bool "Generic x86" + select X86_BOOTLOADER + help + Say Y here if you want barebox to be your BIOS based bootloader + +endchoice + +choice + prompt "Bring up type" + + config X86_BIOS_BRINGUP + prompt "16 bit BIOS" + bool + help + Barebox will act as a BIOS based bootloader. This includes + some 16 bit real mode code and some restrictions everyone knows + from BIOS based systems. + + config X86_NATIVE_BRINGUP + bool "native" + help + Barebox will act as a native bootloader. This includes all the + required initialization needed to bring up a piece of hardware. + Note: Not implemented yet + +endchoice + +source arch/x86/boot/Kconfig +source arch/x86/mach-i386/Kconfig + +source common/Kconfig +source commands/Kconfig +source net/Kconfig +source drivers/Kconfig +source fs/Kconfig +source lib/Kconfig diff --git a/arch/x86/Makefile b/arch/x86/Makefile new file mode 100644 index 0000000000..2e2cb810d7 --- /dev/null +++ b/arch/x86/Makefile @@ -0,0 +1,50 @@ +CPPFLAGS += -D__X86__ -fno-strict-aliasing + +board-y := x86_generic +machine-y := i386 + +TEXT_BASE = $(CONFIG_TEXT_BASE) + +CPPFLAGS += -march=i386 -DTEXT_BASE=$(TEXT_BASE) -P + +ifndef CONFIG_MODULES +# Add cleanup flags +CPPFLAGS += -fdata-sections -ffunction-sections +LDFLAGS_uboot += -static --gc-sections +endif + +ifeq ($(incdir-y),) +incdir-y := $(machine-y) +endif +INCDIR := arch-$(incdir-y) + +all: $(KBUILD_IMAGE) + + + + + + +ifneq ($(board-y),) +BOARD := board/$(board-y)/ +else +BOARD := +endif + +ifneq ($(machine-y),) +MACH := arch/x86/mach-$(machine-y)/ +else +MACH := +endif + +common-y += $(BOARD) $(MACH) +common-y += arch/x86/lib/ +common-y += arch/x86/boot/ + +# arch/x86/cpu/ + +lds-$(CONFIG_GENERIC_LINKER_SCRIPT) := arch/x86/lib/barebox.lds +lds-$(CONFIG_BOARD_LINKER_SCRIPT) := $(BOARD)/barebox.lds + +CLEAN_FILES += arch/x86/lib/barebox.lds barebox.map barebox.S + diff --git a/arch/x86/boot/Kconfig b/arch/x86/boot/Kconfig new file mode 100644 index 0000000000..cdb82e46d9 --- /dev/null +++ b/arch/x86/boot/Kconfig @@ -0,0 +1,20 @@ +if X86_BIOS_BRINGUP + +menu "BIOS boot source " + +config X86_HDBOOT + bool "HD boot" + help + Add code to boot from harddisk + +config X86_VESA + bool + default y if X86_GENERIC_HAS_VIDEO + +config X86_VGA + bool + default y if X86_GENERIC_HAS_VIDEO + +endmenu + +endif diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile new file mode 100644 index 0000000000..b92b4750fc --- /dev/null +++ b/arch/x86/boot/Makefile @@ -0,0 +1,13 @@ + +CPPFLAGS += -D__I386__ -fno-strict-aliasing -m32 -g -Os -march=i386 \ + -mregparm=3 -fno-strict-aliasing -fomit-frame-pointer -ffreestanding \ + -fno-toplevel-reorder -fno-unit-at-a-time -fno-stack-protector \ + -mpreferred-stack-boundary=2 + +obj-$(CONFIG_X86_HDBOOT) += boot_main.o boot_hdisk.o + +obj-$(CONFIG_X86_BIOS_BRINGUP) += prepare_uboot.o a20.o bioscall.o regs.o tty.o pmjump.o main_entry.o + +obj-$(CONFIG_X86_VESA) += console_vesa.o +obj-$(CONFIG_X86_VGA) += console_vga.o +obj-$(CONFIG_X86_SERIAL) += console_serial.o diff --git a/arch/x86/boot/a20.c b/arch/x86/boot/a20.c new file mode 100644 index 0000000000..4b61d91930 --- /dev/null +++ b/arch/x86/boot/a20.c @@ -0,0 +1,170 @@ +/* -*- linux-c -*- ------------------------------------------------------- * + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright 2007-2008 rPath, Inc. - All Rights Reserved + * Copyright 2009 Intel Corporation; author H. Peter Anvin + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2. + * + * ----------------------------------------------------------------------- */ + +/* + * Enable A20 gate (return -1 on failure) + */ + +#include <asm/segment.h> +#include <asm/io.h> +#include "boot.h" + +#define MAX_8042_LOOPS 100000 +#define MAX_8042_FF 32 + +/* be aware of: */ +THIS_IS_REALMODE_CODE + +static int __bootcode empty_8042(void) +{ + u8 status; + int loops = MAX_8042_LOOPS; + int ffs = MAX_8042_FF; + + while (loops--) { + io_delay(); + + status = inb(0x64); + if (status == 0xff) { + /* FF is a plausible, but very unlikely status */ + if (!--ffs) + return -1; /* Assume no KBC present */ + } + if (status & 1) { + /* Read and discard input data */ + io_delay(); + (void)inb(0x60); + } else if (!(status & 2)) { + /* Buffers empty, finished! */ + return 0; + } + } + + return -1; +} + +/* Returns nonzero if the A20 line is enabled. The memory address + used as a test is the int $0x80 vector, which should be safe. */ + +#define A20_TEST_ADDR (4*0x80) +#define A20_TEST_SHORT 32 +#define A20_TEST_LONG 2097152 /* 2^21 */ + +static int __bootcode a20_test(int loops) +{ + int ok = 0; + int saved, ctr; + + set_fs(0x0000); + set_gs(0xffff); + + saved = ctr = rdfs32(A20_TEST_ADDR); + + while (loops--) { + wrfs32(++ctr, A20_TEST_ADDR); + io_delay(); /* Serialize and make delay constant */ + ok = rdgs32(A20_TEST_ADDR+0x10) ^ ctr; + if (ok) + break; + } + + wrfs32(saved, A20_TEST_ADDR); + return ok; +} + +/* Quick test to see if A20 is already enabled */ +static int __bootcode a20_test_short(void) +{ + return a20_test(A20_TEST_SHORT); +} + +/* Longer test that actually waits for A20 to come on line; this + is useful when dealing with the KBC or other slow external circuitry. */ +static int __bootcode a20_test_long(void) +{ + return a20_test(A20_TEST_LONG); +} + +static void __bootcode enable_a20_bios(void) +{ + struct biosregs ireg; + + initregs(&ireg); + ireg.ax = 0x2401; + intcall(0x15, &ireg, NULL); +} + +static void __bootcode enable_a20_kbc(void) +{ + empty_8042(); + + outb(0xd1, 0x64); /* Command write */ + empty_8042(); + + outb(0xdf, 0x60); /* A20 on */ + empty_8042(); + + outb(0xff, 0x64); /* Null command, but UHCI wants it */ + empty_8042(); +} + +static void __bootcode enable_a20_fast(void) +{ + u8 port_a; + + port_a = inb(0x92); /* Configuration port A */ + port_a |= 0x02; /* Enable A20 */ + port_a &= ~0x01; /* Do not reset machine */ + outb(port_a, 0x92); +} + +/* + * Actual routine to enable A20; return 0 on ok, -1 on failure + */ + +#define A20_ENABLE_LOOPS 255 /* Number of times to try */ + +int __bootcode enable_a20(void) +{ + int loops = A20_ENABLE_LOOPS; + int kbc_err; + + while (loops--) { + /* First, check to see if A20 is already enabled + (legacy free, etc.) */ + if (a20_test_short()) + return 0; + + /* Next, try the BIOS (INT 0x15, AX=0x2401) */ + enable_a20_bios(); + if (a20_test_short()) + return 0; + + /* Try enabling A20 through the keyboard controller */ + kbc_err = empty_8042(); + + if (a20_test_short()) + return 0; /* BIOS worked, but with delayed reaction */ + + if (!kbc_err) { + enable_a20_kbc(); + if (a20_test_long()) + return 0; + } + + /* Finally, try enabling the "fast A20 gate" */ + enable_a20_fast(); + if (a20_test_long()) + return 0; + } + + return -1; +} diff --git a/arch/x86/boot/bioscall.S b/arch/x86/boot/bioscall.S new file mode 100644 index 0000000000..84d2577eb6 --- /dev/null +++ b/arch/x86/boot/bioscall.S @@ -0,0 +1,99 @@ +/* ----------------------------------------------------------------------- + * + * Copyright 2009 Intel Corporation; author H. Peter Anvin + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2 or (at your + * option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * "Glove box" for BIOS calls. Avoids the constant problems with BIOSes + * touching registers they shouldn't be. + */ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + .file "bioscall.S" + .code16 + .section .boot.text.intcall, "ax" + + .globl intcall + .type intcall, @function +intcall: + /* Self-modify the INT instruction. Ugly, but works. */ + cmpb %al, 3f + je 1f + movb %al, 3f + jmp 1f /* Synchronize pipeline */ +1: + /* Save state */ + pushfl + pushw %fs + pushw %gs + pushal + + /* Copy input state to stack frame */ + subw $44, %sp + movw %dx, %si + movw %sp, %di + movw $11, %cx + rep; movsd + + /* Pop full state from the stack */ + popal + popw %gs + popw %fs + popw %es + popw %ds + popfl + + /* Actual INT */ + .byte 0xcd /* INT opcode */ +3: .byte 0 + + /* Push full state to the stack */ + pushfl + pushw %ds + pushw %es + pushw %fs + pushw %gs + pushal + + /* Re-establish C environment invariants */ + cld + movzwl %sp, %esp + movw %cs, %ax + movw %ax, %ds + movw %ax, %es + + /* Copy output state from stack frame */ + movw 68(%esp), %di /* Original %cx == 3rd argument */ + andw %di, %di + jz 4f + movw %sp, %si + movw $11, %cx + rep; movsd +4: addw $44, %sp + + /* Restore state and return */ + popal + popw %gs + popw %fs + popfl + retl + .size intcall, .-intcall + +/* ------------------------------------------------------------------------ */ + .code16 + .section .boot.text.die, "ax" + + .globl die + .type die, @function +die: + hlt + jmp die + .size die, .-die + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h new file mode 100644 index 0000000000..d98b0661cd --- /dev/null +++ b/arch/x86/boot/boot.h @@ -0,0 +1,193 @@ +/* -*- linux-c -*- ------------------------------------------------------- * + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright 2007 rPath, Inc. - All Rights Reserved + * Copyright 2009 Intel Corporation; author H. Peter Anvin + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2. + * + * ----------------------------------------------------------------------- */ + +/** + * @file + * @brief Main declarations for the real mode code + */ + +#ifndef BOOT_BOOT_H +#define BOOT_BOOT_H + +#define STACK_SIZE 512 /* Minimum number of bytes for stack */ + +/** Carry flag */ +#define X86_EFLAGS_CF 0x00000001 + +/** PE flag */ +#define X86_CR0_PE 0x00000001 + +#ifndef __ASSEMBLY__ + +#include <types.h> + +/* we are still in real mode here! */ +#define THIS_IS_REALMODE_CODE asm(".code16gcc"); + +struct biosregs { + union { + struct { + uint32_t edi; + uint32_t esi; + uint32_t ebp; + uint32_t _esp; + uint32_t ebx; + uint32_t edx; + uint32_t ecx; + uint32_t eax; + uint32_t _fsgs; + uint32_t _dses; + uint32_t eflags; + }; + struct { + uint16_t di, hdi; + uint16_t si, hsi; + uint16_t bp, hbp; + uint16_t _sp, _hsp; + uint16_t bx, hbx; + uint16_t dx, hdx; + uint16_t cx, hcx; + uint16_t ax, hax; + uint16_t gs, fs; + uint16_t es, ds; + uint16_t flags, hflags; + }; + struct { + uint8_t dil, dih, edi2, edi3; + uint8_t sil, sih, esi2, esi3; + uint8_t bpl, bph, ebp2, ebp3; + uint8_t _spl, _sph, _esp2, _esp3; + uint8_t bl, bh, ebx2, ebx3; + uint8_t dl, dh, edx2, edx3; + uint8_t cl, ch, ecx2, ecx3; + uint8_t al, ah, eax2, eax3; + }; + }; +}; + +/* functions in the realmode part */ +extern int enable_a20(void); +extern void initregs(struct biosregs *regs); +extern void intcall(uint8_t int_no, const struct biosregs *ireg, struct biosregs *oreg); +extern void boot_puts(char*); +extern void __attribute__((noreturn)) die(void); +extern void __attribute__((noreturn)) protected_mode_jump(void); + +struct gdt_ptr { + uint16_t len; + uint32_t ptr; +} __attribute__((packed)); + +/* These functions are used to reference data in other segments. */ + +static inline uint16_t ds(void) +{ + uint16_t seg; + asm("movw %%ds,%0" : "=rm" (seg)); + return seg; +} + +static inline void set_fs(uint16_t seg) +{ + asm volatile("movw %0,%%fs" : : "rm" (seg)); +} + +static inline uint16_t fs(void) +{ + uint16_t seg; + asm volatile("movw %%fs,%0" : "=rm" (seg)); + return seg; +} + +static inline void set_gs(uint16_t seg) +{ + asm volatile("movw %0,%%gs" : : "rm" (seg)); +} + +static inline uint16_t gs(void) +{ + uint16_t seg; + asm volatile("movw %%gs,%0" : "=rm" (seg)); + return seg; +} + +typedef unsigned int addr_t; + +static inline uint8_t rdfs8(addr_t addr) +{ + uint8_t v; + asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*(uint8_t *)addr)); + return v; +} +static inline uint16_t rdfs16(addr_t addr) +{ + uint16_t v; + asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*(uint16_t *)addr)); + return v; +} +static inline uint32_t rdfs32(addr_t addr) +{ + uint32_t v; + asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*(uint32_t *)addr)); + return v; +} + +static inline void wrfs8(uint8_t v, addr_t addr) +{ + asm volatile("movb %1,%%fs:%0" : "+m" (*(uint8_t *)addr) : "qi" (v)); +} +static inline void wrfs16(uint16_t v, addr_t addr) +{ + asm volatile("movw %1,%%fs:%0" : "+m" (*(uint16_t *)addr) : "ri" (v)); +} +static inline void wrfs32(uint32_t v, addr_t addr) +{ + asm volatile("movl %1,%%fs:%0" : "+m" (*(uint32_t *)addr) : "ri" (v)); +} + +static inline uint8_t rdgs8(addr_t addr) +{ + uint8_t v; + asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*(uint8_t *)addr)); + return v; +} +static inline uint16_t rdgs16(addr_t addr) +{ + uint16_t v; + asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*(uint16_t *)addr)); + return v; +} +static inline uint32_t rdgs32(addr_t addr) +{ + uint32_t v; + asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*(uint32_t *)addr)); + return v; +} + +static inline void wrgs8(uint8_t v, addr_t addr) +{ + asm volatile("movb %1,%%gs:%0" : "+m" (*(uint8_t *)addr) : "qi" (v)); +} +static inline void wrgs16(uint16_t v, addr_t addr) +{ + asm volatile("movw %1,%%gs:%0" : "+m" (*(uint16_t *)addr) : "ri" (v)); +} +static inline void wrgs32(uint32_t v, addr_t addr) +{ + asm volatile("movl %1,%%gs:%0" : "+m" (*(uint32_t *)addr) : "ri" (v)); +} + +/** use the built in memset function for the real mode code */ +#define memset(d,c,l) __builtin_memset(d,c,l) + +#endif /* __ASSEMBLY__ */ + +#endif /* BOOT_BOOT_H */ diff --git a/arch/x86/boot/boot_hdisk.S b/arch/x86/boot/boot_hdisk.S new file mode 100644 index 0000000000..40388e993d --- /dev/null +++ b/arch/x86/boot/boot_hdisk.S @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This code was inspired by the GRUB2 project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Loading the barebox image from a disk drive in LBA mode + */ + +/** + * @fn void real_start(void) + * @brief A very simple and small loader to fetch all required sectors + * from the boot media. + */ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + .file "boot_hdisk.S" + .code16 + + /* + * These symbols are generated by the linker, because they need a + * special layout. This layout is needed to be able to setup this + * bootloader by patching the binary when it gets stored into the + * master boot record. + */ + .extern indirect_sector_lba + .extern boot_stack + .extern start_pre_uboot + .extern boot_disk + .section .boot_code, "ax" + + .globl real_start + .type real_start, @function + +real_start: + + xorw %ax, %ax /* set up %ds and %ss as offset from 0 */ + movw %ax, %ds + movw %ax, %ss + + /* set up the REAL stack */ + movw $boot_stack, %sp + + sti /* we're safe again */ + + /* save drive reference first thing! */ + movb %dl, boot_disk + pushw %dx + + movw $notification_string, %si + call output_message + + /* + * This boot code only supports LBA. We fail here, if the BIOS + * does not support LBA for the harddisk + */ + + /* check if LBA is supported */ + movb $0x41, %ah + movw $0x55aa, %bx + int $0x13 + + /* + * %dl may have been clobbered by INT 13, AH=41H. + * This happens, for example, with AST BIOS 1.04. + */ + popw %dx + pushw %dx + + /* stop if no LBA support */ + jc no_lba + cmpw $0xaa55, %bx + jne no_lba + andw $1, %cx + jz no_lba + +lba_mode: + /* + * Load the indirect sector. Its content is ready for use, + * provided by the installer + */ + movw $indirect_sector_lba, %si + movb $0x42, %ah + int $0x13 + jc no_lba /* error? Then die */ + + /* + * Now loop through all valid entries in the indirect sector + */ + movw $indirect_area, %si + +load_loop: + /* + * Stop if this "Disk Address Packet Structure" is invalid + * We call it invalid, if the size member is zero. If it is invalid + * we are optimistic and calling the loaded image + */ + movw (%si), %ax + cmpw $0x0000, %ax + je start_main + + /* + * Load this entry + */ + movb $0x42, %ah + int $0x13 + jc no_lba + + addw (%si), %si /* next entry */ + cmpw $indirect_area + 512, %si + jne load_loop + /* + * fall through to start u-boot. + */ +start_main: + movw $jmp_string, %si + call output_message + jmp start_pre_uboot +/* + * die if there is no LBA support + */ +no_lba: movw $chs_string, %si + call output_message + hlt + +/* + * message: write the string pointed to by %si + * + * WARNING: trashes %si, %ax, and %bx + */ + +/* + * Use BIOS "int 10H Function 0Eh" to write character in teletype mode + * %ah = 0xe %al = character + * %bh = page %bl = foreground color (graphics modes) + */ + +1: + movw $0x0001, %bx + movb $0xe, %ah + int $0x10 /* display this char */ + +output_message: + lodsb + cmpb $0, %al + jne 1b /* if not end of string, next char */ + ret + +/* ---------------------------------------------------------------------- */ + + .section .boot_data + +notification_string: .asciz "UBOOT2 " +chs_string: .asciz "CHS " +jmp_string: .asciz "JMP " + +#endif diff --git a/arch/x86/boot/boot_main.S b/arch/x86/boot/boot_main.S new file mode 100644 index 0000000000..f3d248ae5b --- /dev/null +++ b/arch/x86/boot/boot_main.S @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This code was inspired by the GRUB2 project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Common boot sector main routine to be entered by the BIOS + */ +/** + * @fn void _start(void) + * + * @brief Fix segment:offset settings of some buggy BIOSs + */ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + .file "boot_main.S" + .code16 + + .extern real_start + + .section .boot_start, "ax" + .type _start, @function + + /* + * The BIOS loads this code to address 0x00007c00. + * The code should be called with CS:IP 0:0x7c00 (hopefully). + */ + .globl _start +_start: + cli /* we're not safe here! */ + /* + * It seems there are implementations in the wild which call this + * code with CS:IP 0x07C0:0000 instead. We fix it immediately. + */ + ljmp $0, $real_start + + .size _start, .-_start + +#endif diff --git a/arch/x86/boot/main_entry.c b/arch/x86/boot/main_entry.c new file mode 100644 index 0000000000..5f199e985b --- /dev/null +++ b/arch/x86/boot/main_entry.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Start of the 32 bit flat mode + */ + +#include <string.h> + +/* These symbols are generated by the linker */ +extern char __bss_start; +extern char __bss_end; + +extern void start_barebox(void); + +/** + * Called plainly from assembler that switches from real to flat mode + * + * @note The C environment isn't initialized yet + */ +void uboot_entry(void) +{ + /* clear the BSS first */ + memset(&__bss_start, 0x00, &__bss_end - &__bss_start); + start_barebox(); +} diff --git a/arch/x86/boot/pmjump.S b/arch/x86/boot/pmjump.S new file mode 100644 index 0000000000..d48e1983f1 --- /dev/null +++ b/arch/x86/boot/pmjump.S @@ -0,0 +1,89 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright 2007 rPath, Inc. - All Rights Reserved + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2. + * + * ----------------------------------------------------------------------- */ + +/** + * @file + * @brief The actual transition into protected mode + * + * Note: This function is running in flat and real mode. Due to some + * other restrictions it must running from an address space below 0x10000 + */ + +/** + * @fn void protected_mode_jump(void) + * @brief Switches the first time from real mode to flat mode + */ +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#include <asm/modes.h> +#include "boot.h" + + .file "pmjump.S" + .code16 + .section .boot.text.protected_mode_jump, "ax" + + .globl protected_mode_jump + .type protected_mode_jump, @function + +protected_mode_jump: + jmp 1f /* Short jump to serialize on 386/486 */ +1: + + movw $__BOOT_DS, %cx + movw $__BOOT_TSS, %di + + movl %cr0, %edx + orb $X86_CR0_PE, %dl /* enable protected mode */ + movl %edx, %cr0 + + /* Transition to 32-bit flat mode */ + data32 ljmp $__BOOT_CS, $in_pm32 + +/* ------------------------------------------------------------------------ */ + + .section ".text.in_pm32","ax" + .code32 + + .extern uboot_entry + .extern __bss_end + + .type in_pm32, @function +in_pm32: + # Set up data segments for flat 32-bit mode + movl %ecx, %ds + movl %ecx, %es + movl %ecx, %fs + movl %ecx, %gs + movl %ecx, %ss +/* + * Our flat mode code uses its own stack area behind the bss. With this we + * are still able to return to real mode temporarely + */ + movl $__bss_end + 32768, %esp + + # Set up TR to make Intel VT happy + ltr %di + + # Clear registers to allow for future extensions to the + # 32-bit boot protocol + xorl %ecx, %ecx + xorl %edx, %edx + xorl %ebx, %ebx + xorl %ebp, %ebp + xorl %edi, %edi + + # Set up LDTR to make Intel VT happy + lldt %cx + + jmp uboot_entry + + .size protected_mode_jump, .-protected_mode_jump + +#endif diff --git a/arch/x86/boot/prepare_uboot.c b/arch/x86/boot/prepare_uboot.c new file mode 100644 index 0000000000..a68aceddb6 --- /dev/null +++ b/arch/x86/boot/prepare_uboot.c @@ -0,0 +1,86 @@ +/* -*- linux-c -*- ------------------------------------------------------- * + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright 2007 rPath, Inc. - All Rights Reserved + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2. + * + * ----------------------------------------------------------------------- */ + +/* + * Prepare the machine for transition to protected mode. + */ +#include <asm/segment.h> +#include <asm/modes.h> +#include <asm/io.h> +#include "boot.h" + +/* be aware of: */ +THIS_IS_REALMODE_CODE + +/* + * While we are in flat mode, we can't handle interrupts. But we can't + * switch them off for ever in the PIC, because we need them again while + * entering real mode code again and again.... + */ +static void __bootcode realmode_switch_hook(void) +{ + asm volatile("cli"); + outb(0x80, 0x70); /* Disable NMI */ + io_delay(); +} + +/* + * Reset IGNNE# if asserted in the FPU. + */ +static void __bootcode reset_coprocessor(void) +{ + outb(0, 0xf0); + io_delay(); + outb(0, 0xf1); + io_delay(); +} + +/** + * Setup and register the global descriptor table (GDT) + * + * @note This is for the first time only + */ +static void __bootcode setup_gdt(void) +{ + /* Xen HVM incorrectly stores a pointer to the gdt_ptr, instead + of the gdt_ptr contents. Thus, make it static so it will + stay in memory, at least long enough that we switch to the + proper kernel GDT. */ + static struct gdt_ptr __bootdata gdt_ptr; + + gdt_ptr.len = gdt_size - 1; + gdt_ptr.ptr = (uint32_t)&gdt + (ds() << 4); + + asm volatile("lgdtl %0" : : "m" (gdt_ptr)); +} + +static char a20_message[] __bootdata = "A20 gate not responding, unable to boot...\n"; + +/* + * Actual invocation sequence + */ +void __bootcode start_pre_uboot(void) +{ + /* Hook before leaving real mode, also disables interrupts */ + realmode_switch_hook(); + + /* Enable the A20 gate */ + if (enable_a20()) { + boot_puts(a20_message); + die(); + } + + /* Reset coprocessor (IGNNE#) */ + reset_coprocessor(); + + setup_gdt(); + /* Actual transition to protected mode... */ + protected_mode_jump(); +} diff --git a/arch/x86/boot/regs.c b/arch/x86/boot/regs.c new file mode 100644 index 0000000000..ddc515518c --- /dev/null +++ b/arch/x86/boot/regs.c @@ -0,0 +1,34 @@ +/* ----------------------------------------------------------------------- + * + * Copyright 2009 Intel Corporation; author H. Peter Anvin + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2 or (at your + * option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/** + * @file + * @brief Simple helper function for initializing a register set. + * + * Note that this sets EFLAGS_CF in the input register set; this + * makes it easier to catch functions which do nothing but don't + * explicitly set CF. + */ + +#include <asm/segment.h> +#include "boot.h" + +/* be aware of: */ +THIS_IS_REALMODE_CODE + +void __bootcode initregs(struct biosregs *reg) +{ + memset(reg, 0, sizeof *reg); + reg->eflags |= X86_EFLAGS_CF; + reg->ds = ds(); + reg->es = ds(); + reg->fs = fs(); + reg->gs = gs(); +} diff --git a/arch/x86/boot/tty.c b/arch/x86/boot/tty.c new file mode 100644 index 0000000000..a81671be3b --- /dev/null +++ b/arch/x86/boot/tty.c @@ -0,0 +1,45 @@ +/* -*- linux-c -*- ------------------------------------------------------- * + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright 2007 rPath, Inc. - All Rights Reserved + * Copyright 2009 Intel Corporation; author H. Peter Anvin + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2. + * + * ----------------------------------------------------------------------- */ + +/** + * @file + * @brief Very simple screen I/O for the initialization stage + * + * @todo Probably should add very simple serial I/O? + * @attention This is real mode code! + */ + +#include <asm/segment.h> +#include "boot.h" + +/* be aware of: */ +THIS_IS_REALMODE_CODE + +static void __bootcode putchar(int ch) +{ + struct biosregs ireg; + + if (ch == '\n') + putchar('\r'); /* \n -> \r\n */ + + initregs(&ireg); + ireg.bx = 0x0007; + ireg.cx = 0x0001; + ireg.ah = 0x0e; + ireg.al = ch; + intcall(0x10, &ireg, NULL); +} + +void __bootcode boot_puts(char *str) +{ + while (*str) + putchar(*str++); +} diff --git a/arch/x86/configs/generic_defconfig b/arch/x86/configs/generic_defconfig new file mode 100644 index 0000000000..091f696e3a --- /dev/null +++ b/arch/x86/configs/generic_defconfig @@ -0,0 +1,186 @@ +# +# Automatically generated make config: don't edit +# barebox version: 2009.12.0-x86-trunk +# +CONFIG_ARCH_TEXT_BASE=0x00007c00 +CONFIG_BOARDINFO="Generic x86 bootloader" +# CONFIG_BOARD_LINKER_SCRIPT is not set +CONFIG_GENERIC_LINKER_SCRIPT=y +CONFIG_X86=y +CONFIG_MACH_X86_GENERIC=y +CONFIG_X86_BIOS_BRINGUP=y +# CONFIG_X86_NATIVE_BRINGUP is not set + +# +# BIOS boot source +# +CONFIG_X86_HDBOOT=y + +# +# Board specific settings +# +CONFIG_GREGORIAN_CALENDER=y +CONFIG_HAS_KALLSYMS=y +CONFIG_HAS_MODULES=y +CONFIG_CMD_MEMORY=y +CONFIG_ENV_HANDLING=y + +# +# General Settings +# +CONFIG_LOCALVERSION_AUTO=y + +# +# memory layout +# +CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y +CONFIG_TEXT_BASE=0x00007c00 +CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y +CONFIG_MEMORY_LAYOUT_DEFAULT=y +# CONFIG_MEMORY_LAYOUT_FIXED is not set +CONFIG_STACK_SIZE=0x7000 +CONFIG_MALLOC_SIZE=0x400000 +CONFIG_BROKEN=y +CONFIG_EXPERIMENTAL=y +# CONFIG_MODULES is not set +# CONFIG_KALLSYMS is not set +CONFIG_PROMPT="uboot:" +CONFIG_BAUDRATE=115200 +CONFIG_LONGHELP=y +CONFIG_CBSIZE=1024 +CONFIG_MAXARGS=16 +CONFIG_SHELL_HUSH=y +# CONFIG_SHELL_SIMPLE is not set +CONFIG_GLOB=y +CONFIG_PROMPT_HUSH_PS2="> " +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_DYNAMIC_CRC_TABLE=y +CONFIG_ERRNO_MESSAGES=y +CONFIG_TIMESTAMP=y +CONFIG_CONSOLE_FULL=y +CONFIG_CONSOLE_ACTIVATE_FIRST=y +# CONFIG_OF_FLAT_TREE is not set +CONFIG_PARTITION=y +CONFIG_DEFAULT_ENVIRONMENT=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="board/x86_generic/env" + +# +# Debugging +# +CONFIG_DEBUG_INFO=y +# CONFIG_ENABLE_FLASH_NOISE is not set +# CONFIG_ENABLE_PARTITION_NOISE is not set +# CONFIG_ENABLE_DEVICE_NOISE is not set + +# +# Commands +# + +# +# scripting +# +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +# CONFIG_CMD_TRUE is not set +# CONFIG_CMD_FALSE is not set + +# +# file commands +# +CONFIG_CMD_LS=y +CONFIG_CMD_RM=y +CONFIG_CMD_CAT=y +CONFIG_CMD_MKDIR=y +CONFIG_CMD_RMDIR=y +CONFIG_CMD_CP=y +CONFIG_CMD_PWD=y +CONFIG_CMD_CD=y +CONFIG_CMD_MOUNT=y +CONFIG_CMD_UMOUNT=y + +# +# console +# +CONFIG_CMD_CLEAR=y +CONFIG_CMD_ECHO=y + +# +# memory +# +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADY is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MEMINFO=y +# CONFIG_CMD_CRC is not set +# CONFIG_CMD_MTEST is not set + +# +# flash +# +# CONFIG_CMD_FLASH is not set + +# +# booting +# +# CONFIG_CMD_BOOTM is not set +CONFIG_CMD_LINUX16=y +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_TIMEOUT=y +# CONFIG_CMD_PARTITION is not set +CONFIG_CMD_TEST=y +CONFIG_CMD_VERSION=y +CONFIG_CMD_HELP=y +CONFIG_CMD_DEVINFO=y +# CONFIG_NET is not set + +# +# Drivers +# + +# +# serial drivers +# +CONFIG_DRIVER_SERIAL_NS16550=y + +# +# SPI drivers +# +# CONFIG_SPI is not set +# CONFIG_I2C is not set + +# +# flash drivers +# +# CONFIG_DRIVER_CFI is not set +# CONFIG_DRIVER_CFI_OLD is not set +# CONFIG_NAND is not set +CONFIG_ATA=y + +# +# drive types +# +CONFIG_ATA_DISK=y + +# +# interface types +# +CONFIG_ATA_BIOS=y +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set +# CONFIG_VIDEO is not set + +# +# Filesystem support +# +# CONFIG_FS_CRAMFS is not set +CONFIG_FS_RAMFS=y +CONFIG_FS_DEVFS=y +CONFIG_CRC32=y +# CONFIG_GENERIC_FIND_NEXT_BIT is not set diff --git a/arch/x86/include/asm/barebox.h b/arch/x86/include/asm/barebox.h new file mode 100644 index 0000000000..39bea1844b --- /dev/null +++ b/arch/x86/include/asm/barebox.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* nothing special yet */ diff --git a/arch/x86/include/asm/barebox.lds.h b/arch/x86/include/asm/barebox.lds.h new file mode 100644 index 0000000000..6cbf15f5cf --- /dev/null +++ b/arch/x86/include/asm/barebox.lds.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Adapt linker script content in accordance to Kconfig settings + */ + +#define INITCALLS \ + KEEP(*(.initcall.0)) \ + KEEP(*(.initcall.1)) \ + KEEP(*(.initcall.2)) \ + KEEP(*(.initcall.3)) \ + KEEP(*(.initcall.4)) \ + KEEP(*(.initcall.5)) \ + KEEP(*(.initcall.6)) \ + KEEP(*(.initcall.7)) + +#define BAREBOX_CMDS KEEP(*(SORT_BY_NAME(.barebox_cmd*))) + +#define BAREBOX_SYMS KEEP(*(__usymtab)) + +/** + * Area in the MBR of the barebox basic boot code. This offset must be in + * accordance to the 'indirect_sector_lba' label. + */ +#define PATCH_AREA 400 + +/** + * Offset where to store the boot drive number (BIOS number, 1 byte) + */ +#define PATCH_AREA_BOOT_DEV 16 + +/** + * Offset where to store information about the persistant environment storage + * It points to an LBA number (8 bytes) and defines the first sector of this + * storage on disk. + */ +#define PATCH_AREA_PERS_START 20 + +/** + * Offset where to store information about the persistant environment storage + * It points to a short number (2 bytes) and defines the sector count of this + * storage on disk. + */ +#define PATCH_AREA_PERS_SIZE 28 + +/** + * Offset where to store information about the persistant environment storage + * drive number (BIOS number, 1 byte) + */ +#define PATCH_AREA_PERS_DRIVE 30 + +/** + * Mark the persistant environment as not used + */ +#define PATCH_AREA_PERS_SIZE_UNUSED 0x000 + +/** + * Mark a DAPS as unused/invalid + */ +#define MARK_DAPS_INVALID 0x0000 + +/** + * Offset of the partition table in an MBR + */ +#define OFFSET_OF_PARTITION_TABLE 446 + +/** + * Offset of the signature in an MBR + */ +#define OFFSET_OF_SIGNATURE 510 + +/** + * Area where to store indirect sector to loop through. Keep this value + * in accordance to the 'indirect_area' label. Note: . + * + * @attention These addresses are real mode ones (seg:offset) + */ +#define INDIRECT_AREA 0x7A00 +#define INDIRECT_SEGMENT 0x0000 + +/** + * Area where to load sectors from disk to. They should start after the + * MBR area and must be in accordance to the offset of the '.bootstrapping' + * section in the linker file. + * + * @attention The address must be a multiple of 512. + */ +#define LOAD_AREA 0x7e00 +#define LOAD_SEGMENT 0x0000 + +/** + * Size of one sector. + */ +#define SECTOR_SIZE 512 diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h new file mode 100644 index 0000000000..b43afa3f99 --- /dev/null +++ b/arch/x86/include/asm/bitops.h @@ -0,0 +1,32 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief x86 bit operations + * + * This file is required only to make all sources happy including + * 'linux/bitops.h' + */ + +#ifndef _ASM_X86_BITOPS_H_ +#define _ASM_X86_BITOPS_H_ + +/* nothing special yet */ + +#endif /* _ASM_X86_BITOPS_H_ */ diff --git a/arch/x86/include/asm/byteorder.h b/arch/x86/include/asm/byteorder.h new file mode 100644 index 0000000000..51ce8e1d51 --- /dev/null +++ b/arch/x86/include/asm/byteorder.h @@ -0,0 +1,30 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief x86 endianess declaration + */ + +#ifndef __ASM_X86_BYTEORDER_H +#define __ASM_X86_BYTEORDER_H + +#include <asm/types.h> +#include <linux/byteorder/little_endian.h> + +#endif diff --git a/arch/x86/include/asm/common.h b/arch/x86/include/asm/common.h new file mode 100644 index 0000000000..4862680e44 --- /dev/null +++ b/arch/x86/include/asm/common.h @@ -0,0 +1,29 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief x86 common declarations + */ + +#ifndef _ASM_X86_COMMON_H_ +#define _ASM_X86_COMMON_H_ + +/* Nothing exiting yet */ + +#endif /* _ASM_X86_COMMON_H_ */ diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h new file mode 100644 index 0000000000..01342d6aef --- /dev/null +++ b/arch/x86/include/asm/elf.h @@ -0,0 +1,30 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief x86 specific elf information + * + */ + +#ifndef _ASM_X86_ELF_H +#define _ASM_X86_ELF_H + +#define ELF_CLASS ELFCLASS32 + +#endif /* _ASM_X86_ELF_H */ diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h new file mode 100644 index 0000000000..27ea642527 --- /dev/null +++ b/arch/x86/include/asm/io.h @@ -0,0 +1,73 @@ +/* + * Mostly stolen from the linux kernel + */ + +/** + * @file + * @brief x86 IO access functions + */ + +#ifndef __ASM_X86_IO_H +#define __ASM_X86_IO_H + +static inline void outb(unsigned char value, int port) +{ + asm volatile("outb %b0, %w1" : : "a"(value), "Nd"(port)); +} + +static inline void outw(unsigned short value, int port) +{ + asm volatile("outw %w0, %w1" : : "a"(value), "Nd"(port)); +} + +static inline void outl(unsigned long value, int port) +{ + asm volatile("outl %0, %w1" : : "a"(value), "Nd"(port)); +} + +static inline unsigned char inb(int port) +{ + unsigned char value; + asm volatile("inb %w1, %b0" : "=a"(value) : "Nd"(port)); + return value; +} + +static inline unsigned short inw(int port) +{ + unsigned short value; + asm volatile("inw %w1, %w0" : "=a"(value) : "Nd"(port)); + return value; +} + +static inline unsigned long inl(int port) +{ + unsigned long value; + asm volatile("inl %w1, %0" : "=a"(value) : "Nd"(port)); + return value; +} + +#define build_mmio_read(name, size, type, reg, barrier) \ + static inline type name(const volatile void *addr) \ + { type ret; asm volatile("mov" size " %1,%0":reg (ret) \ + :"m" (*(volatile type*)addr) barrier); return ret; } + +build_mmio_read(readb, "b", unsigned char, "=q", :"memory") +build_mmio_read(readw, "w", unsigned short, "=r", :"memory") +build_mmio_read(readl, "l", unsigned int, "=r", :"memory") + +#define build_mmio_write(name, size, type, reg, barrier) \ + static inline void name(type val, volatile void *addr) \ + { asm volatile("mov" size " %0,%1": :reg (val), \ + "m" (*(volatile type*)addr) barrier); } + +build_mmio_write(writeb, "b", unsigned char, "q", :"memory") +build_mmio_write(writew, "w", unsigned short, "r", :"memory") +build_mmio_write(writel, "l", unsigned int, "r", :"memory") + +/* do a tiny io delay */ +static inline void io_delay(void) +{ + inb(0x80); +} + +#endif /* __ASM_X86_IO_H */ diff --git a/arch/x86/include/asm/modes.h b/arch/x86/include/asm/modes.h new file mode 100644 index 0000000000..8417ddc4b5 --- /dev/null +++ b/arch/x86/include/asm/modes.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Declarations to bring some light in the real/protected/flat mode darkness + */ +#ifndef _ASM_X86_MODES_H +#define _ASM_X86_MODES_H + +#ifndef __ASSEMBLY__ + +#include <types.h> + +extern uint64_t gdt[]; +extern unsigned gdt_size; + +#endif + +/** to simplify GDT entry generation */ +#define GDT_ENTRY(flags, base, limit) \ + ((((base) & 0xff000000ULL) << (56-24)) | \ + (((flags) & 0x0000f0ffULL) << 40) | \ + (((limit) & 0x000f0000ULL) << (48-16)) | \ + (((base) & 0x00ffffffULL) << 16) | \ + (((limit) & 0x0000ffffULL))) + +/** 32 bit barebox text */ +#define GDT_ENTRY_BOOT_CS 2 +#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8) + +/** 32 bit barebox data */ +#define GDT_ENTRY_BOOT_DS 3 +#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) + +/** 16 bit barebox text */ +#define GDT_ENTRY_REAL_CS 4 +#define __REAL_CS (GDT_ENTRY_REAL_CS * 8) + +/** 16 bit barebox data */ +#define GDT_ENTRY_REAL_DS 5 +#define __REAL_DS (GDT_ENTRY_REAL_DS * 8) + +/** Something to make others happy */ +#define GDT_ENTRY_BOOT_TSS 6 +#define __BOOT_TSS (GDT_ENTRY_BOOT_TSS * 8) + +#endif /* _ASM_X86_MODES_H */ diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h new file mode 100644 index 0000000000..168e91df24 --- /dev/null +++ b/arch/x86/include/asm/module.h @@ -0,0 +1,37 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief x86 module support + * + */ + +#ifndef _ASM_X86_MODULE_H_ +#define _ASM_X86_MODULE_H_ + +/** currently nothing special */ +struct mod_arch_specific +{ + int foo; +}; + +#define Elf_Shdr Elf32_Shdr +#define Elf_Ehdr Elf32_Ehdr + +#endif /* _ASM_X86_MODULE_H_ */ diff --git a/arch/x86/include/asm/posix_types.h b/arch/x86/include/asm/posix_types.h new file mode 100644 index 0000000000..a22f301aee --- /dev/null +++ b/arch/x86/include/asm/posix_types.h @@ -0,0 +1,49 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief x86 posix types + * + * Minimal set to make all the other header files copied from the Linxu kernel happy + */ + +#ifndef _ASM_X86_POSIX_TYPES_H +#define _ASM_X86_POSIX_TYPES_H + +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_dev_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; +typedef long long __kernel_loff_t; + +#endif /* _ASM_X86_POSIX_TYPES_H */ diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h new file mode 100644 index 0000000000..cb9b3d0c5c --- /dev/null +++ b/arch/x86/include/asm/segment.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _ASM_X86_SEGMENT_H +#define _ASM_X86_SEGMENT_H + +#include <linux/compiler.h> + +/** + * @file + * @brief To be able to mark functions running in real _and_ flat mode + */ + +/** + * Section for every program code needed to bring barebox from real mode + * to flat mode + */ +#define __bootcode __section(.boot.text) + +/** + * Section for every data needed to bring barebox from real mode + * to flat mode + */ +#define __bootdata __section(.boot.data) + +#endif /* _ASM_X86_SEGMENT_H */ diff --git a/arch/x86/include/asm/string.h b/arch/x86/include/asm/string.h new file mode 100644 index 0000000000..5ca2ff1af0 --- /dev/null +++ b/arch/x86/include/asm/string.h @@ -0,0 +1,31 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief x86 specific string optimizations + * + * Thanks to the Linux kernel here we can add many micro optimized string + * functions. But currently it makes no sense, to do so. + */ +#ifndef __ASM_X86_STRING_H +#define __ASM_X86_STRING_H + +/* nothing special yet */ + +#endif diff --git a/arch/x86/include/asm/syslib.h b/arch/x86/include/asm/syslib.h new file mode 100644 index 0000000000..eebe1a99c9 --- /dev/null +++ b/arch/x86/include/asm/syslib.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +extern unsigned int x86_uart_read(unsigned long, unsigned char); +extern void x86_uart_write(unsigned int, unsigned long, unsigned char); + +#ifdef CONFIG_X86_BIOS_BRINGUP + +extern int bios_disk_rw_int13_extensions(int, int, void*) __attribute__((regparm(3))); +extern uint16_t bios_get_memsize(void); + +#endif + +#ifdef CONFIG_CMD_LINUX16 +extern void bios_start_linux(unsigned) __attribute__((regparm(1))); +#endif diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h new file mode 100644 index 0000000000..17c5fd7b9c --- /dev/null +++ b/arch/x86/include/asm/types.h @@ -0,0 +1,44 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_X86_TYPES_H +#define __ASM_X86_TYPES_H + +#ifndef __ASSEMBLY__ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +typedef __signed__ long long __s64; +typedef unsigned long long __u64; + +typedef unsigned char u8; + +typedef unsigned short u16; + +typedef unsigned int u32; + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_X86_TYPES_H */ diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile new file mode 100644 index 0000000000..b67629f115 --- /dev/null +++ b/arch/x86/lib/Makefile @@ -0,0 +1,9 @@ +extra-$(CONFIG_GENERIC_LINKER_SCRIPT) += barebox.lds +obj-y += memory.o +obj-y += gdt.o + +# needed, when running via a 16 bit BIOS +obj-$(CONFIG_X86_BIOS_BRINGUP) += memory16.o +obj-$(CONFIG_X86_BIOS_BRINGUP) += traveler.o +obj-$(CONFIG_X86_BIOS_BRINGUP) += bios_disk.o +obj-$(CONFIG_CMD_LINUX16) += linux_start.o diff --git a/arch/x86/lib/barebox.lds.S b/arch/x86/lib/barebox.lds.S new file mode 100644 index 0000000000..2917d2fa12 --- /dev/null +++ b/arch/x86/lib/barebox.lds.S @@ -0,0 +1,194 @@ +/* + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#undef i386 +#include <asm/barebox.lds.h> + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +MEMORY +{ + mbr(rwx): ORIGIN = TEXT_BASE, LENGTH = 2 * SECTOR_SIZE + barebox (rwx) : ORIGIN = TEXT_BASE + SECTOR_SIZE, LENGTH = (256 * 1024 * 1024) +} + +SECTIONS +{ +#ifdef CONFIG_X86_HDBOOT + + .ramlayout : { + boot_stack = INDIRECT_AREA; + indirect_area = INDIRECT_AREA; + } + /* describing the main boot sector */ + .bootsector : AT (0) { + *(.boot_start) + + . = 0x00b; + /* + * Maybe later on occupied by a "BIOS parameter block". So, + * keep it free from code. + * - BytesPerSector dw@0x000B + * - SectorsPerCluster db@0x000D + * - ReservedSectors dw@0x000E + * - FatCopies db@0x0010 + * - RootDirEntries dw@0x0011 + * - NumSectors dw@0x0013 + * - MediaType db@0x0015 + * - SectorsPerFAT dw@0x0016 + * - SectorsPerTrack dw@0x0018 + * - NumberOfHeads dw@0x001A + * - HiddenSectors dd@0x001C + * - SectorsBig dd@0x0020 + */ + LONG(0); + + . = 0x024; + *(.boot_code) + *(.boot_data) + + /* + * embed one "Disk Address Packet Structure" into the boot sector + * This DAPS points to the 'indirect' sector to give the boot code + * an idea what and where to load. Its content must be adapted + * to the system it should run on, so, this structure must be + * located at a well known offset. + */ + . = PATCH_AREA; + indirect_sector_lba = .; + SHORT(0x0010); /* size of this structure */ + SHORT(0x0001); /* one sector */ + SHORT(indirect_area); /* where to store: offset */ + SHORT(0x0000); /* where to store: segment */ + /* the following values are filled by the installer */ + LONG(0x00000000); /* LBA start lower */ + LONG(0x00000000); /* LBA start upper */ + + /* boot disk number used by upper layers */ + . = PATCH_AREA + PATCH_AREA_BOOT_DEV; + boot_disk = .; + BYTE(0x00); /* boot disk number (provided by the BIOS) + + /* information about the persistant environment storage */ + . = PATCH_AREA + PATCH_AREA_PERS_START; + pers_env_storage = .; + LONG(0x00000000); /* LBA start lower */ + LONG(0x00000000); /* LBA start upper */ + + . = PATCH_AREA + PATCH_AREA_PERS_SIZE; + pers_env_size = .; + SHORT(PATCH_AREA_PERS_SIZE_UNUSED); /* size of this area in sectors */ + + . = PATCH_AREA + PATCH_AREA_PERS_DRIVE; + pers_env_drive = .; + BYTE(0x00); /* used drive */ + + /* partition table area (fixed location) */ + . = OFFSET_OF_PARTITION_TABLE; + /* create an empty one */ + LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); + LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); + LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); + LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); LONG(0x00000000); + + /* boot sector signature */ + . = OFFSET_OF_SIGNATURE; + BYTE(0x55); + BYTE(0xAA); + /* end of the first sector */ + + /* + * The indirect sector starts here + */ + . = SECTOR_SIZE; + BYTE(MARK_DAPS_INVALID); /* mark the first entry invalid */ + BYTE(0x00); + . = SECTOR_SIZE + 496; + BYTE(MARK_DAPS_INVALID); /* mark the last entry invalid */ + BYTE(0x00); + . = SECTOR_SIZE + 508; + LONG(0x00000000); /* LBA start upper */ + } > mbr + + /* some real mode bootstrapping */ + .bootstrapping : AT ( LOADADDR(.bootsector) + SIZEOF(.bootsector) ) { + *(.boot.head) + *(.boot.text*) + *(.boot.rodata*) + *(.boot.data*) + . = ALIGN(4); + } > barebox +#endif + + /* the main barebox part (32 bit) */ + .text : AT ( LOADADDR(.bootstrapping) + SIZEOF(.bootstrapping) ) { + /* do not align here! It may fails with the LOADADDR! */ + _stext = .; + *(.text_entry*) + *(.text_bare_init*) + *(.text*) + . = ALIGN(4); + *(.rodata*) + . = ALIGN(4); + _etext = .; /* End of text and rodata section */ + } > barebox + + .data : AT ( LOADADDR(.text) + SIZEOF(.text) ) { + *(.data*) + . = ALIGN(4); + } > barebox + + .got : AT ( LOADADDR(.data) + SIZEOF (.data) ) { + *(.got*) + . = ALIGN(4); + } > barebox + + .barebox_cmd : AT ( LOADADDR(.got) + SIZEOF (.got) ) { + __barebox_cmd_start = .; + BAREBOX_CMDS + __barebox_cmd_end = .; + . = ALIGN(4); + } > barebox + + .barebox_initcalls : AT ( LOADADDR(.barebox_cmd) + SIZEOF (.barebox_cmd) ) { + __barebox_initcalls_start = .; + INITCALLS + __barebox_initcalls_end = .; + . = ALIGN(4); + } > barebox + + .__usymtab : AT ( LOADADDR(.barebox_initcalls) + SIZEOF (.barebox_initcalls) ) { + __usymtab_start = .; + BAREBOX_SYMS + __usymtab_end = .; + . = ALIGN(4); + } > barebox + + .bss : { + __bss_start = .; + *(.bss*); + *( COMMON ) + __bss_end = .; + _end = .; + } > barebox +} diff --git a/arch/x86/lib/bios_disk.S b/arch/x86/lib/bios_disk.S new file mode 100644 index 0000000000..3acd66047d --- /dev/null +++ b/arch/x86/lib/bios_disk.S @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * Mostly stolen from the GRUB2 project + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Do BIOS calls to load or save data from disks + * + * @note These functions are running in flat and real mode. Due to some + * other restrictions these routines must running from an address + * space below 0x10000 + */ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +/* + * int bios_disk_rw_int13_extensions (int ah, int drive, void *dap) + * + * Call IBM/MS INT13 Extensions (int 13 %ah=AH) for DRIVE. DAP + * is passed for disk address packet. If an error occurs, return + * non-zero, otherwise zero. + */ + .section .boot.text.bios_disk_rw_int13_extensions, "ax" + .code32 + .globl bios_disk_rw_int13_extensions + .type bios_disk_rw_int13_extensions, @function + + .extern prot_to_real + .extern real_to_prot + +bios_disk_rw_int13_extensions: + pushl %ebp + pushl %esi + + /* compute the address of disk_address_packet */ + movw %cx, %si + xorw %cx, %cx + shrl $4, %ecx /* save the segment to cx */ + + movb %al, %dh + call prot_to_real /* enter real mode right now */ + + .code16 + movb %dh, %ah + movw %cx, %ds + int $0x13 /* do the operation */ + movb %ah, %dl /* save return value */ + /* back to protected mode */ + DATA32 call real_to_prot + + .code32 + movb %dl, %al /* return value in %eax */ + + popl %esi + popl %ebp + + ret + +#endif diff --git a/arch/x86/lib/gdt.c b/arch/x86/lib/gdt.c new file mode 100644 index 0000000000..a9c4d0e9dd --- /dev/null +++ b/arch/x86/lib/gdt.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Definition of the Global Descriptor Table + */ + +#include <types.h> +#include <asm/modes.h> +#include <asm/segment.h> + +/** + * The 'Global Descriptor Table' used in barebox + * + * Note: This table must reachable by real and flat mode code + */ +uint64_t gdt[] __attribute__((aligned(16))) __bootdata = { + /* CS: code, read/execute, 4 GB, base 0 */ + [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff), + /* DS: data, read/write, 4 GB, base 0 */ + [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff), + /* CS: for real mode calls */ + [GDT_ENTRY_REAL_CS] = GDT_ENTRY(0x009E, 0, 0x0ffff), + /* DS: for real mode calls */ + [GDT_ENTRY_REAL_DS] = GDT_ENTRY(0x0092, 0, 0x0ffff), + /* TSS: 32-bit tss, 104 bytes, base 4096 */ + /* We only have a TSS here to keep Intel VT happy; + we don't actually use it for anything. */ + [GDT_ENTRY_BOOT_TSS] = GDT_ENTRY(0x0089, 4096, 103), +}; + +/** + * Size of the GDT must be known to load it + * + * Note: This varibale must reachable by real and flat mode code + */ +unsigned gdt_size __bootdata = sizeof(gdt); diff --git a/arch/x86/lib/linux_start.S b/arch/x86/lib/linux_start.S new file mode 100644 index 0000000000..fac2510d1c --- /dev/null +++ b/arch/x86/lib/linux_start.S @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * Mostly stolen from the GRUB2 project + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Start the Linux real mode setup code + * + * Note: These functions are running in flat and real mode. Due to some + * other restrictions these routines must running from an address + * space below 0x10000 + */ + +/* + * void bios_start_linux(unsigned segment) + * + */ +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + .section .boot.text.bios_start_linux, "ax" + .code32 + .globl bios_start_linux + .type bios_start_linux, @function + + .extern prot_to_real + +bios_start_linux: + /* 'prot_to_real' eats our eax content */ + movl %eax, %ebx + addl $0x20, %eax + movw %ax, setup_seg + + call prot_to_real + + .code16 + + cli + /* all segment registers are using the same segment */ + movw %bx, %ss + movw %bx, %ds + movw %bx, %es + movw %bx, %fs + movw %bx, %gs + + /* stack for the setup code (end of heap) */ + movw $0x9000, %sp + + /* do an 'ljmp' and never return */ + .byte 0xea + .word 0 +setup_seg: + .word 0 + + .code32 + +#endif diff --git a/arch/x86/lib/memory.c b/arch/x86/lib/memory.c new file mode 100644 index 0000000000..9496d2277f --- /dev/null +++ b/arch/x86/lib/memory.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This code was inspired by the GRUB2 project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Memory management + */ + +#include <init.h> +#include <stdio.h> +#include <mem_malloc.h> +#include <asm/syslib.h> +#include <asm-generic/memory_layout.h> + +/** + * Handling of free memory + * + * Topics: + * - areas used by BIOS code + * - The 0xa0000... 0xfffff hole + * - memory above 0x100000 + */ + +static int x86_mem_malloc_init(void) +{ +#ifdef CONFIG_MEMORY_LAYOUT_DEFAULT + unsigned long memory_size; + + memory_size = bios_get_memsize(); + memory_size <<= 10; /* BIOS reports in kiB */ + + /* + * We do not want to conflict with the kernel. So, we keep the + * area from 0x100000 ... 0xFFFFFF free from usage + */ + if (memory_size >= (15 * 1024 * 1024 + MALLOC_SIZE)) + mem_malloc_init((void*)(16 * 1024 * 1024), + (void*)(16 * 1024 * 1024) + MALLOC_SIZE); + else + return -1; +#else + mem_malloc_init((void *)MALLOC_BASE, + (void *)(MALLOC_BASE + MALLOC_SIZE)); +#endif + return 0; +} + +core_initcall(x86_mem_malloc_init); diff --git a/arch/x86/lib/memory16.S b/arch/x86/lib/memory16.S new file mode 100644 index 0000000000..01450fa596 --- /dev/null +++ b/arch/x86/lib/memory16.S @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This code was inspired by the GRUB2 project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Query the memory layout information from the BIOS + * + * Note: This function is running in flat and real mode. Due to some + * other restrictions it must running from an address space below 0x10000 + */ + +/** + * @fn unsigned short bios_get_memsize(void) + * @brief Does a BIOS call "INT 15H, AH=88H" to get extended memory size + * @return Extended memory size in KB + * + * @note This call is limited to 64 MiB. So, if the system provides more than + * 64 MiB of memory, still 64 MiB are reported. + * + */ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + .section .boot.text.bios_get_memsize, "ax" + .code32 + .globl bios_get_memsize + .type bios_get_memsize, @function + + .extern prot_to_real + +bios_get_memsize: + + pushl %ebp + + call prot_to_real /* enter real mode */ + .code16 + + movb $0x88, %ah + int $0x15 + + movw %ax, %dx + + DATA32 call real_to_prot + + .code32 + + movw %dx, %ax + + popl %ebp + ret + + .size bios_get_memsize, .-bios_get_memsize + +#endif diff --git a/arch/x86/lib/traveler.S b/arch/x86/lib/traveler.S new file mode 100644 index 0000000000..2b6dc85ed2 --- /dev/null +++ b/arch/x86/lib/traveler.S @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * Mostly stolen from the GRUB2 project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Switch from the flat mode world into the real mode world and vice versa + * + * Note: These functions are *called* and return in a different operating mode + */ + +/** + * @fn void real_to_prot(void) + * @brief Switch from temp. real mode back to flat mode + * + * Called from a 32 bit flat mode segment and returns into a 16 bit segment + */ + +/** + * @fn void prot_to_real(void) + * @brief Switch from flat mode to real mode + * + * Called from a 16 bit real mode segment and returns into a 32 bit segment + */ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#include <asm/modes.h> + + .file "walkyrie.S" + +/* keep the current flat mode stack pointer, while playing in real mode */ + .section .boot.data.protstack + .code32 +protstack: .long 4 +/* temp. store */ +return_addr: .long 4 + + + .section .boot.text.real_to_prot, "ax" + .code16 + .globl real_to_prot + .type real_to_prot, @function + +/* Note: This routine should not change any other standard registers than eax */ +real_to_prot: + /* + * Always disable the interrupts, when returning to flat mode + */ + cli + + /* turn on protected mode */ + movl %cr0, %eax + orl $0x00000001, %eax + movl %eax, %cr0 + + /* jump to relocation, flush prefetch queue, and reload %cs */ + DATA32 ljmp $__BOOT_CS, $return_to_flatmode + +/* ----------------------------------------------------------------------- */ + .section .boot.text.return_to_flatmode, "ax" + .type return_to_flatmode, @function + .code32 + +return_to_flatmode: + /* reload other segment registers */ + movw $__BOOT_DS, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + /* move the return address from the real mode to the flat mode stack */ + movl (%esp), %eax + movl %eax, return_addr + + /* setup again the flat mode stack */ + movl protstack, %eax + movl %eax, %esp + movl %eax, %ebp + + movl return_addr, %eax + movl %eax, (%esp) + + /* flag we returned happy here */ + xorl %eax, %eax + ret + + .size real_to_prot, .-real_to_prot + +/* ------------------------------------------------------------------------ */ + +/* Note: This routine should not change any other standard registers than eax */ + + .section .boot.text.prot_to_real, "ax" + .globl prot_to_real + .type prot_to_real, @function + .extern boot_stack + .code32 + +prot_to_real: + /* save the protected mode stack */ + movl %esp, %eax + movl %eax, protstack + + /* prepare the real mode stack */ + /* - address to call to the top of this stack */ + movl (%esp), %eax + movl %eax, boot_stack - 4 + + /* - the stack itself */ + movl $boot_stack - 4, %eax + movl %eax, %esp + movl %eax, %ebp + + /* prepare segments limits to 16 bit */ + movw $__REAL_DS, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + /* at last, also limit the code segment to 16 bit */ + ljmp $__REAL_CS, $return_to_realmode + +/* ----------------------------------------------------------------------- */ + + .section .boot.text.return_to_realmode, "ax" +return_to_realmode: + .code16 + + /* disable protected mode */ + movl %cr0, %eax + andl $(~0x00000001), %eax + movl %eax, %cr0 + + /* + * all the protected mode settings are still cached in the CPU. + * Refresh them by re-loading all registers in realmode + * Start with the CS, continue with the data registers + */ + ljmp $0, $enter_realmode + +enter_realmode: + xorl %eax, %eax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + /* + * back in plain real mode now, we can play again with the BIOS + */ + + /* restore interrupts */ + sti + + /* return on realmode stack! */ + DATA32 ret + + .size prot_to_real, .-prot_to_real + +#endif diff --git a/arch/x86/mach-i386/Kconfig b/arch/x86/mach-i386/Kconfig new file mode 100644 index 0000000000..11f6aa679a --- /dev/null +++ b/arch/x86/mach-i386/Kconfig @@ -0,0 +1,29 @@ + +menu "Board specific settings " + +if X86_BOOTLOADER + +config X86_GENERIC_HAS_ISA + bool "ISA support" + help + Say Y here if the target supports a ISA bus + +config X86_GENERIC_HAS_PCI + bool "PCI support" + select HAS_PCI + help + Say Y here if the target supports a PCI bus + +config X86_GENERIC_HAS_VIDEO + bool "video support" + help + Say Y here if the target supports a video output + +config X86_GENERIC_HAS_USB + bool "USB support" + help + Say Y here if the target supports a USB interface + +endif + +endmenu diff --git a/arch/x86/mach-i386/Makefile b/arch/x86/mach-i386/Makefile new file mode 100644 index 0000000000..10712e6a3b --- /dev/null +++ b/arch/x86/mach-i386/Makefile @@ -0,0 +1,5 @@ +obj-y += generic.o +obj-y += reset.o + +# reference clocksource +obj-y += pit_timer.o diff --git a/arch/x86/mach-i386/generic.c b/arch/x86/mach-i386/generic.c new file mode 100644 index 0000000000..edeacc4275 --- /dev/null +++ b/arch/x86/mach-i386/generic.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief x86 Architecture Initialization routines + */ + +#include <asm/io.h> + +/** to work with the 8250 UART driver implementation we need this function */ +unsigned int x86_uart_read(unsigned long base, unsigned char reg_idx) +{ + return inb(base + reg_idx); +} + +/** to work with the 8250 UART driver implementation we need this function */ +void x86_uart_write(unsigned int val, unsigned long base, unsigned char reg_idx) +{ + outb(val, base + reg_idx); +} diff --git a/arch/x86/mach-i386/pit_timer.c b/arch/x86/mach-i386/pit_timer.c new file mode 100644 index 0000000000..b9f805e61f --- /dev/null +++ b/arch/x86/mach-i386/pit_timer.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Clocksource based on the 'Programmable Interval Timer' PIT (8253) + * + * This timer should be available on almost all PCs. It also should be run + * at a fixed frequency (1193181.8181 Hz) and not modified to use another + * reload value than 0xFFFF. So, it always counts from 0xffff down to 0. + * + * @note: We can't reprogram the PIT, it will be still used by the BIOS. This + * clocksource driver does not touch any PIT settings. + */ + +#include <init.h> +#include <clock.h> +#include <asm/io.h> + +/** base address of the PIT in a standard PC */ +#define PIT 0x40 + +static uint64_t pit_clocksource_read(void) +{ + uint16_t val1, val2; + + outb(0x00, PIT + 3); /* latch counter 0 */ + outb(0x00, 0x80); + + val1 = inb(PIT); + outb(0x00, 0x80); + + val2 = inb(PIT); + val2 <<= 8; + + /* note: its a down counter */ + return 0xFFFFU - (val1 | val2); +} + +static struct clocksource cs = { + .read = pit_clocksource_read, + .mask = 0x0000ffff, + .shift = 10, +}; + +static int clocksource_init (void) +{ + cs.mult = clocksource_hz2mult(1193182, cs.shift); + init_clock(&cs); + + return 0; +} + +core_initcall(clocksource_init); diff --git a/arch/x86/mach-i386/reset.c b/arch/x86/mach-i386/reset.c new file mode 100644 index 0000000000..a4eb364870 --- /dev/null +++ b/arch/x86/mach-i386/reset.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/** + * @file + * @brief Resetting an x86 CPU + */ + +#include <common.h> + +void reset_cpu(ulong addr) +{ + /** How to reset the machine? */ + while(1) + ; +} +EXPORT_SYMBOL(reset_cpu); diff --git a/arch/x86/mach-x86.dox b/arch/x86/mach-x86.dox new file mode 100644 index 0000000000..fc5b85a081 --- /dev/null +++ b/arch/x86/mach-x86.dox @@ -0,0 +1,128 @@ +/* This document is intended to provide the developer with information + * how to integrate a new CPU (MACH) into this part of the barebox tree + */ + +/** @page x86_runtime barebox on x86 at runtime + +@section mach_x86_memory_layout barebox's memory layout (BIOS based) + +@a barebox uses the following memory layout at runtime when it still depends +on some kind of BIOS function: + +@verbatim + Addresses +------------------------ + + seg:off flat + +xxxx:xxxx 0x01xxxxxx end of barebox's malloc area + . . +xxxx:xxxx 0x01000000 start of barebox's malloc area + . . + . . (used while loading a Linux kernel of type 'bzImage') + . . +xxxx:xxxx 0x00100000 start of extended memory and malloc area + . . + . . (the big hole) + . . +9000:ffff 0x0009ffff end of expected real mode memory + . . + . . (used while loading a Linux kernel of type 'bzImage') + . . +9000:0000 0x00090000 end of used lower real mode memory + . . + . . + . . Flat mode stack (about 32 kiB) + . . bss + . . Data + . . Text +0000:7e00 0x00007e00 Real and flat mode barebox code +0000:7c00 0x00007c00 MBR initial boot loader code +0000:7a00 0x00007a00 location of the indirect sector (while booting only) + below: real mode stack +@endverbatim + +@note The start address of 0x0000:7c000 is a fixed one, defined by the BIOS. +So, for a BIOS based @a barebox this address can't be changed. + +While the @a barebox code is runnung in flat mode, all interrupts are disabled. +But in the CPU only. All other interrupt settings are still valid. This is +required to be able to call real mode code from inside @a barebox flat mode +code. Thats why not the PIC is touched nor the IDT. + +@todo Add some notes about drive numbers used by the BIOS. They may change +if one change orders in the BIOS setup. Drive orders and numbers may be +different at BIOS runtime and Linux runtime! But these numbers are required +at BIOS runtime for booting and the persistant environment storage. + +@attention Currently there is a 4 GiB limit for the disk sizes! + +@section mach_x86_image_layout barebox's image layout + +@a barebox's binary image layout + +@verbatim + Offset Content + + 0x????? + . 32 bit barebox code + . + . 16 bit bootstrap code, BIOS calling code + 0x00400 + 0x003ff + . indirect sector + 0x00200 + 0x001ff + . MBR + 0x00000 +@endverbatim + +The "indirect sector" is a free area in the image where the sector information +gets stored when this image will be written to a boot media. This information +is required to load all parts of the image from the boot media at runtime. + +The image gets installed in two ways onto the boot media, depending on the +need for a persistant storage. + +@subsection mach_x86_drive_layout_wops barebox's boot media layout without persistant storage + +In this case @a barebox's persistant storage is anywhere: + +@verbatim + Sector Content +--------------------------- + X start of first partition + . + ? end of the binary image + . 32 bit barebox code + 2 16 bit bootstrap code, BIOS calling code + 1 indirect sector + 0 MBR, Partition table, boot code +@endverbatim + +@subsection mach_x86_drive_layout_wps barebox's boot media layout with persistant storage + +@a barebox's persistant storage is part of the boot media (more +space required in front of the first partition) and interferes with the +boot loader image itself: + +@verbatim + Sector Content +--------------------------- + X start of first partition + . + n+? end of the binary image + . 32 bit barebox code + n+2 16 bit bootstrap code, BIOS calling code + n+1 indirect sector + n end of persistant environment storage + . + 1 start of persistant environment storage + 0 MBR, Partition table, boot code +@endverbatim + +The information where the persistant storage is located is also stored into +the MBR at specific locations by @p setupmbr. The @a barebox runtime will use +it to load and store all environment relevant data. + +*/ |