diff --git a/src/mainboard/nintendo/switch/Kconfig b/src/mainboard/nintendo/switch/Kconfig index e347930212..e485604c6e 100644 --- a/src/mainboard/nintendo/switch/Kconfig +++ b/src/mainboard/nintendo/switch/Kconfig @@ -18,11 +18,8 @@ if BOARD_NINTENDO_SWITCH config BOARD_SPECIFIC_OPTIONS # dummy def_bool y select BOARD_ROMSIZE_KB_16384 - select COMMON_CBFS_SPI_WRAPPER #select MAINBOARD_HAS_NATIVE_VGA_INIT #select MAINBOARD_FORCE_NATIVE_VGA_INIT - select SPI_FLASH - select SPI_FLASH_WINBOND select SOC_NVIDIA_TEGRA210 #select MAINBOARD_DO_DSI_INIT diff --git a/src/mainboard/nintendo/switch/Makefile.inc b/src/mainboard/nintendo/switch/Makefile.inc index 642ca44903..d609d7bdc1 100644 --- a/src/mainboard/nintendo/switch/Makefile.inc +++ b/src/mainboard/nintendo/switch/Makefile.inc @@ -26,6 +26,7 @@ subdirs-y += bct bootblock-y += bootblock.c bootblock-y += pmic.c bootblock-y += reset.c +bootblock-y += cbfs_switch.c verstage-y += reset.c @@ -33,12 +34,14 @@ romstage-y += pmic.c romstage-y += reset.c romstage-y += romstage.c romstage-y += sdram_configs.c +romstage-y += cbfs_switch.c ramstage-y += boardid.c ramstage-y += mainboard.c ramstage-y += reset.c ramstage-y += pmic.c ramstage-y += sdram_configs.c +ramstage-y += cbfs_switch.c bootblock-y += memlayout.ld romstage-y += memlayout.ld diff --git a/src/mainboard/nintendo/switch/cbfs_switch.c b/src/mainboard/nintendo/switch/cbfs_switch.c new file mode 100644 index 0000000000..d4d67a779a --- /dev/null +++ b/src/mainboard/nintendo/switch/cbfs_switch.c @@ -0,0 +1,147 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2018 Andre Heider + * + * 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; version 2 of the License. + * + * 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. + */ + +#include +#include +#include + +#include "cbfs_switch.h" + +#define UINT32TOBUF(val, x, o) \ + do { \ + x[o + 0] = (val >> 24) & 0xff; \ + x[o + 1] = (val >> 16) & 0xff; \ + x[o + 2] = (val >> 8) & 0xff; \ + x[o + 3] = val & 0xff; \ + } while (0); + +extern u8 _usb_bounce[]; +extern u8 _eusb_bounce[]; +#define _usb_bounce_size (_eusb_bounce - _usb_bounce) + +extern u8 _rom_copy[]; +extern u8 _erom_copy[]; +#define _rom_copy_size (_erom_copy - _rom_copy) + +typedef struct { + char is_usb3; + char init_hw_done; + char init_proto_done; + char unk0; + + int (*init_hw)(void); + int (*init_proto)(void); + + void *ep1_out; + void *ep1_out_get_len_proc_ep0; + void (*ep1_out_imm)(void *buffer, uint32_t size, uint32_t *num_xfer); + + void *ep1_in; + void *ep1_in_get_len_proc_ep0; + int (*ep1_in_imm)(void *buffer, uint32_t size, uint32_t *num_xfer); + + void *ep0_stall; +} rcm_transport_t; + +static const rcm_transport_t *rcm_transport = (rcm_transport_t *)0x40003114; + +static u32 rom_recvbuf(void *buffer, u32 size) { + u32 num_xfer; + rcm_transport->ep1_out_imm(buffer, size, &num_xfer); + return num_xfer; +} + +static u32 rom_sendbuf(void *buffer, u32 size) { + u32 num_xfer; + rcm_transport->ep1_in_imm(buffer, size, &num_xfer); + return num_xfer; +} + +static ssize_t usb_readat(const struct region_device *rd, void *b, + size_t offset, size_t size) +{ + size_t left = size; + size_t chunk; + + UINT32TOBUF(offset, _usb_bounce, 0); + UINT32TOBUF(size, _usb_bounce, 4); + rom_sendbuf(_usb_bounce, 8); + + while (left > 0) { + chunk = left; + if (chunk > _usb_bounce_size) + chunk = _usb_bounce_size; + + chunk = rom_recvbuf(_usb_bounce, chunk); + memcpy(b, _usb_bounce, chunk); + + b += chunk; + left -= chunk; + } + + return size - left; +} + +static const struct region_device_ops usb_ops = { + .mmap = mmap_helper_rdev_mmap, + .munmap = mmap_helper_rdev_munmap, + .readat = usb_readat, +} +; +static struct mmap_helper_region_device mdev_usb = + MMAP_HELPER_REGION_INIT(&usb_ops, 0, CONFIG_ROM_SIZE); + +static struct mem_region_device mdev_sdram = + MEM_REGION_DEV_RO_INIT(_rom_copy, CONFIG_ROM_SIZE); + +#if ENV_RAMSTAGE +static bool rom_in_sdram = true; +#else +static bool rom_in_sdram = false; +#endif + +void cbfs_switch_to_sdram(void) +{ + usb_readat(NULL, _rom_copy, 0, CONFIG_ROM_SIZE); + + memset(_usb_bounce, 0, 8); + rom_sendbuf(_usb_bounce, 8); + + rom_in_sdram = true; +} + +const struct region_device *boot_device_ro(void) +{ + if (rom_in_sdram) + return &mdev_sdram.rdev; + + return &mdev_usb.rdev; +} + +void boot_device_init(void) +{ + void *cache; + size_t size; + + if (ENV_ROMSTAGE) { + cache = _postram_cbfs_cache; + size = _postram_cbfs_cache_size; + } else { + cache = _cbfs_cache; + size = _cbfs_cache_size; + } + + mmap_helper_device_init(&mdev_usb, cache, size); +} diff --git a/src/mainboard/nintendo/switch/cbfs_switch.h b/src/mainboard/nintendo/switch/cbfs_switch.h new file mode 100644 index 0000000000..16b29b50f3 --- /dev/null +++ b/src/mainboard/nintendo/switch/cbfs_switch.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2018 Andre Heider + * + * 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; version 2 of the License. + * + * 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. + */ + +#ifndef __MAINBOARD_NINTENDO_SWITCH_CBFS_SWITCH_H__ +#define __MAINBOARD_NINTENDO_SWITCH_CBFS_SWITCH_H__ + +void cbfs_switch_to_sdram(void); + +#endif /* __MAINBOARD_NINTENDO_SWITCH_CBFS_SWITCH_H__ */ diff --git a/src/mainboard/nintendo/switch/memlayout.ld b/src/mainboard/nintendo/switch/memlayout.ld index 0f8214adae..b80c6c37be 100644 --- a/src/mainboard/nintendo/switch/memlayout.ld +++ b/src/mainboard/nintendo/switch/memlayout.ld @@ -35,11 +35,13 @@ SECTIONS BOOTBLOCK(0x40010000, 28K) ROMSTAGE(0x40017000, 56K) PRERAM_CBMEM_CONSOLE(0x40025000, 8K) - PRERAM_CBFS_CACHE(0x40027000, 100K) + PRERAM_CBFS_CACHE(0x40027000, 92K) + REGION(usb_bounce, 0x4003e000, 8K, 4) SRAM_END(0x40040000) DRAM_START(0x80000000) RAMSTAGE(0x80200000, 256K) POSTRAM_CBFS_CACHE(0xd0000000, 8M) + REGION(rom_copy, 0xd0800000, CONFIG_ROM_SIZE, 4) TTB(0x100000000 - CONFIG_TTB_SIZE_MB * 1M, CONFIG_TTB_SIZE_MB * 1M) } diff --git a/src/mainboard/nintendo/switch/romstage.c b/src/mainboard/nintendo/switch/romstage.c index 09bbed34cc..e741caf357 100644 --- a/src/mainboard/nintendo/switch/romstage.c +++ b/src/mainboard/nintendo/switch/romstage.c @@ -13,15 +13,17 @@ * GNU General Public License for more details. */ +#include #include -#include #include +#include #include #include #include #include #include +#include "cbfs_switch.h" #include "gpio.h" #include "pmic.h" @@ -43,6 +45,10 @@ static const struct pad_config padcfgs[] = { void romstage_mainboard_init(void) { //soc_configure_pads(padcfgs, ARRAY_SIZE(padcfgs)); + + printk(BIOS_INFO, "Switching to SDRAM backed CBFS\n"); + + cbfs_switch_to_sdram(); } void mainboard_configure_pmc(void)