dual: run host_info_to_device_cdc on ea4088_quickstart

The board has both USB ports wired: U1 to the Type-A host connector and U2
to the micro-B device connector, and board_init() already puts the port
select in that mode, so it can run the dual example.

- Allow the example on LPC40XX.
- Point the host stack at rhport 0: ohci maps the TinyUSB rhport onto its
  root-hub port index, and the host controller here is index 0, while the
  dual examples default to rhport 1.
- Move the string-descriptor buffers out of the stack. They are written by
  the host controller, so on parts whose USB master cannot reach the CPU
  stack (this family) the strings came back as garbage. host/device_info
  already keeps its transfer buffer in CFG_TUH_MEM_SECTION; do the same
  here.

Verified on ea4088_quickstart with a WCH-Link on the Type-A port and the
micro-B plugged into a PC:

  mounted device 1
  Device 1: ID 1a86:8010 SN 7FD88F0604B5
    iManufacturer       1     wch.cn
    iProduct            2     WCH-Link
diff --git a/examples/dual/host_info_to_device_cdc/only.txt b/examples/dual/host_info_to_device_cdc/only.txt
index 4431065..d98b67e 100644
--- a/examples/dual/host_info_to_device_cdc/only.txt
+++ b/examples/dual/host_info_to_device_cdc/only.txt
@@ -9,3 +9,4 @@
 mcu:STM32F7
 mcu:STM32H7
 mcu:ESP32P4
+mcu:LPC40XX
diff --git a/examples/dual/host_info_to_device_cdc/src/main.c b/examples/dual/host_info_to_device_cdc/src/main.c
index 5186f91..b542e91 100644
--- a/examples/dual/host_info_to_device_cdc/src/main.c
+++ b/examples/dual/host_info_to_device_cdc/src/main.c
@@ -234,10 +234,10 @@
 // Host Get device information
 //--------------------------------------------------------------------+
 static void print_device_info(uint8_t daddr, const tusb_desc_device_t* desc_device) {
-  // Get String descriptor using Sync API
-  uint16_t serial[64];
-  uint16_t buf[128];
-  (void) buf;
+  // Get String descriptor using Sync API. The buffers are written by the host controller,
+  // so they must sit in memory it can reach (and be cache-line aligned where dcache is on).
+  static CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN uint16_t serial[64];
+  static CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN uint16_t buf[128];
 
   cdc_printf("Device %u: ID %04x:%04x SN ", daddr, desc_device->idVendor, desc_device->idProduct);
   uint8_t xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, serial, sizeof(serial));
diff --git a/hw/bsp/lpc40/family.cmake b/hw/bsp/lpc40/family.cmake
index 5c02caf..7cdc6ef 100644
--- a/hw/bsp/lpc40/family.cmake
+++ b/hw/bsp/lpc40/family.cmake
@@ -35,6 +35,8 @@
     CFG_TUSB_MEM_SECTION=__attribute__\(\(section\(\".data.$RAM2\"\)\)\)
     CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\".data.$RAM2\"\)\)\)
     CFG_TUH_MEM_SECTION=__attribute__\(\(section\(\".data.$RAM2\"\)\)\)
+    # host is on root-hub port index 0; the dual examples would otherwise default it to 1
+    BOARD_TUH_RHPORT=0
     )
   target_include_directories(${BOARD_TARGET} PUBLIC
     ${SDK_DIR}/inc
diff --git a/hw/bsp/lpc40/family.mk b/hw/bsp/lpc40/family.mk
index ad155a2..02903d3 100644
--- a/hw/bsp/lpc40/family.mk
+++ b/hw/bsp/lpc40/family.mk
@@ -10,6 +10,7 @@
   -DCFG_TUSB_MEM_SECTION='__attribute__((section(".data.$$RAM2")))' \
   -DCFG_TUD_MEM_SECTION='__attribute__((section(".data.$$RAM2")))' \
   -DCFG_TUH_MEM_SECTION='__attribute__((section(".data.$$RAM2")))' \
+  -DBOARD_TUH_RHPORT=0 \
   -DCFG_TUSB_MCU=OPT_MCU_LPC40XX
 
 # mcu driver cause following warnings