Showing with 115 additions and 16 deletions.
  1. +10 −1 CHANGELOG.md
  2. +2 −2 src/boot.c
  3. +8 −9 src/hw/usb-xhci.c
  4. +3 −1 src/hw/usb.c
  5. +92 −3 src/sercon.c
11 changes: 10 additions & 1 deletion CHANGELOG.md
Expand Up @@ -5,6 +5,14 @@ Fourth digit in release number means PC Engines patch.

## [Unreleased]

## [rel-1.11.0.3] - 2018-01-31
### Fixed
- timeout issues with USB 3.x

### Added
- support for serial console disabling runtime config
- ATA UDMA enabled

## [rel-1.11.0.2] - 2017-12-22
### Fixed
- bug with serial console printing
Expand Down Expand Up @@ -50,7 +58,8 @@ Fourth digit in release number means PC Engines patch.
### Fixed
- prevented from printing character multiple times

[Unreleased]: https://github.com/pcengines/seabios/compare/rel-1.11.0.2...apu_support
[Unreleased]: https://github.com/pcengines/seabios/compare/rel-1.11.0.3...apu_support
[rel-1.11.0.3]: https://github.com/pcengines/seabios/compare/rel-1.11.0.3...rel-1.11.0.2
[rel-1.11.0.2]: https://github.com/pcengines/seabios/compare/rel-1.11.0.2...rel-1.11.0.1
[rel-1.11.0.1]: https://github.com/pcengines/seabios/compare/rel-1.11.0.1...rel-1.10.2.1
[rel-1.10.2.1]: https://github.com/pcengines/seabios/compare/rel-1.10.2.1...rel-1.10.0.1
Expand Down
4 changes: 2 additions & 2 deletions src/boot.c
Expand Up @@ -31,7 +31,7 @@ static char **Bootorder VARVERIFY32INIT;
static int BootorderCount;

static void
loadBootOrder(void)
loadBootorder(void)
{
if (!CONFIG_BOOTORDER)
return;
Expand Down Expand Up @@ -314,7 +314,7 @@ boot_init(void)

BootRetryTime = romfile_loadint("etc/boot-fail-wait", 60*1000);

loadBootOrder();
loadBootorder();
}


Expand Down
17 changes: 8 additions & 9 deletions src/hw/usb-xhci.c
Expand Up @@ -312,7 +312,7 @@ static int wait_bit(u32 *reg, u32 mask, int value, u32 timeout)
* Root hub
****************************************************************/

#define XHCI_TIME_POSTPOWER 20
#define XHCI_TIME_POSTPOWER 100

// Check if device attached to port
static void
Expand Down Expand Up @@ -354,16 +354,15 @@ xhci_hub_reset(struct usbhub_s *hub, u32 port)
// A USB2 port - perform device reset
xhci_print_port_state(3, __func__, port, portsc);
writel(&xhci->pr[port].portsc, portsc | XHCI_PORTSC_PR);
if (wait_bit(&xhci->pr[port].portsc, XHCI_PORTSC_PED, XHCI_PORTSC_PED, 100) != 0)
if (wait_bit(&xhci->pr[port].portsc, XHCI_PORTSC_PED, XHCI_PORTSC_PED, 1500) != 0)
return -1;
msleep(20); // Patch to make XHCI work on AMD Mullins
break;
default:
return -1;
}

// Wait for device to complete reset and be enabled
u32 end = timer_calc(100);
u32 end = timer_calc(1500);
for (;;) {
portsc = readl(&xhci->pr[port].portsc);
if (!(portsc & XHCI_PORTSC_CCS))
Expand Down Expand Up @@ -464,15 +463,15 @@ configure_xhci(void *data)
if (reg & XHCI_CMD_RS) {
reg &= ~XHCI_CMD_RS;
writel(&xhci->op->usbcmd, reg);
if (wait_bit(&xhci->op->usbsts, XHCI_STS_HCH, XHCI_STS_HCH, 32) != 0)
if (wait_bit(&xhci->op->usbsts, XHCI_STS_HCH, XHCI_STS_HCH, 64) != 0)
goto fail;
}

dprintf(3, "%s: resetting\n", __func__);
writel(&xhci->op->usbcmd, XHCI_CMD_HCRST);
if (wait_bit(&xhci->op->usbcmd, XHCI_CMD_HCRST, 0, 100) != 0)
if (wait_bit(&xhci->op->usbcmd, XHCI_CMD_HCRST, 0, 500) != 0)
goto fail;
if (wait_bit(&xhci->op->usbsts, XHCI_STS_CNR, 0, 100) != 0)
if (wait_bit(&xhci->op->usbsts, XHCI_STS_CNR, 0, 500) != 0)
goto fail;

writel(&xhci->op->config, xhci->slots);
Expand Down Expand Up @@ -527,7 +526,7 @@ configure_xhci(void *data)
reg = readl(&xhci->op->usbcmd);
reg &= ~XHCI_CMD_RS;
writel(&xhci->op->usbcmd, reg);
wait_bit(&xhci->op->usbsts, XHCI_STS_HCH, XHCI_STS_HCH, 32);
wait_bit(&xhci->op->usbsts, XHCI_STS_HCH, XHCI_STS_HCH, 64);

fail:
free(xhci->eseg);
Expand Down Expand Up @@ -797,7 +796,7 @@ static int xhci_cmd_submit(struct usb_xhci_s *xhci, struct xhci_inctx *inctx
mutex_lock(&xhci->cmds->lock);
xhci_trb_queue(xhci->cmds, inctx, 0, flags);
xhci_doorbell(xhci, 0, 0);
int rc = xhci_event_wait(xhci, xhci->cmds, 1000);
int rc = xhci_event_wait(xhci, xhci->cmds, 2000);
mutex_unlock(&xhci->cmds->lock);
return rc;
}
Expand Down
4 changes: 3 additions & 1 deletion src/hw/usb.c
Expand Up @@ -419,7 +419,7 @@ usb_hub_port_setup(void *data)
if (ret < 0 || timer_check(hub->detectend))
// No device found.
goto done;
msleep(5);
msleep(20);
}

// XXX - wait USB_TIME_ATTDB time?
Expand All @@ -432,6 +432,8 @@ usb_hub_port_setup(void *data)
goto resetfail;
usbdev->speed = ret;

msleep(20);

// Set address of port
ret = usb_set_address(usbdev);
if (ret) {
Expand Down
95 changes: 92 additions & 3 deletions src/sercon.c
Expand Up @@ -12,6 +12,7 @@
#include "string.h" // memcpy
#include "romfile.h" // romfile_loadint
#include "hw/serialio.h" // SEROFF_IER
#include "malloc.h"
#include "cp437.h"

static u8 video_rows(void)
Expand Down Expand Up @@ -42,6 +43,85 @@ static void cursor_pos_set(u8 row, u8 col)
SET_BDA(cursor_pos[0], pos);
}

static char **BootOrder VARVERIFY32INIT;
static int BootOrderCount;
static int scon;

static void
loadBootOrder(void)
{
if (!CONFIG_BOOTORDER)
return;

char *f = romfile_loadfile("bootorder", NULL);
if (!f)
return;

int i = 0;
BootOrderCount = 1;
while (f[i]) {
if (f[i] == '\n')
BootOrderCount++;
i++;
}
BootOrder = malloc_tmphigh(BootOrderCount*sizeof(char*));
if (!BootOrder) {
warn_noalloc();
free(f);
BootOrderCount = 0;
return;
}

dprintf(1, "boot order:\n");
i = 0;
do {
BootOrder[i] = f;
f = strchr(f, '\n');
if (f)
*(f++) = '\0';
BootOrder[i] = nullTrailingSpace(BootOrder[i]);
dprintf(1, "%d: %s\n", i+1, BootOrder[i]);
i++;
} while (f);
}

// See if 'str' starts with 'glob' - if glob contains an '*' character
// it will match any number of characters in str that aren't a '/' or
// the next glob character.
static char *
find_glob_prefix(const char *glob, const char *str)
{
for (;;) {
if (!*glob && (!*str || *str == '/'))
return (char*)str;
if (*glob == '*') {
if (!*str || *str == '/' || *str == glob[1])
glob++;
else
str++;
continue;
}
if (*glob != *str)
return NULL;
glob++;
str++;
}
}


static int find_scon(void)
{
int i = 0;
for (i=0; i < BootOrderCount; i++)
{
if (find_glob_prefix("scon0", BootOrder[i]))
return 0;
if (find_glob_prefix("scon1", BootOrder[i]))
return 1;
}
return -1;
}

/****************************************************************
* serial console output
****************************************************************/
Expand Down Expand Up @@ -522,6 +602,11 @@ void sercon_setup(void)
addr = romfile_loadint("etc/sercon-port", 0);
if (!addr)
return;

loadBootOrder();

scon = find_scon();

dprintf(1, "sercon: using ioport 0x%x\n", addr);

if (CONFIG_DEBUG_SERIAL)
Expand All @@ -542,9 +627,13 @@ void sercon_setup(void)
}

SET_IVT(0x10, FUNC16(entry_sercon));
SET_LOW(sercon_port, addr);
outb(0x03, addr + SEROFF_LCR); // 8N1
outb(0x01, addr + 0x02); // enable fifo
if(!scon) {
SET_LOW(sercon_enable, 0);
} else {
SET_LOW(sercon_port, addr);
outb(0x03, addr + SEROFF_LCR); // 8N1
outb(0x01, addr + 0x02); // enable fifo
}
}

/****************************************************************
Expand Down