0e1a90ea1d
This streamlines the boot code a bit and reduces target specific boilerplate. The clock init hack used by the bootloader has been "standardized" and works for the main Rockbox binary now, so you can boot rockbox.bin over USB without special hacks. Change-Id: I7c1fac37df5a45873583ce6818eaedb9f71a782b
91 lines
2.5 KiB
C
91 lines
2.5 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2021 Aidan MacDonald
|
|
*
|
|
* 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef __BOOT_X1000_H__
|
|
#define __BOOT_X1000_H__
|
|
|
|
#include "x1000/cpm.h"
|
|
#include <stdbool.h>
|
|
|
|
enum {
|
|
BOOT_OPTION_ROCKBOX = 0,
|
|
BOOT_OPTION_OFW_PLAYER,
|
|
BOOT_OPTION_OFW_RECOVERY,
|
|
};
|
|
|
|
enum {
|
|
/* 3 bits to store the boot option selected by the SPL */
|
|
BOOT_OPTION_MASK = 0x7,
|
|
BOOT_OPTION_SHIFT = 0,
|
|
|
|
/* Set after running clk_init() and setting up system clocks */
|
|
BOOT_FLAG_CLK_INIT = (1 << 31),
|
|
|
|
/* Set by the SPL if it was loaded over USB boot */
|
|
BOOT_FLAG_USB_BOOT = (1 << 30),
|
|
};
|
|
|
|
/* Note: these functions are inlined to minimize SPL code size.
|
|
* They are private to the X1000 early boot code anyway... */
|
|
|
|
static inline void cpm_scratch_set(uint32_t value)
|
|
{
|
|
/* TODO: see if this holds its state over a WDT reset */
|
|
REG_CPM_SCRATCH_PROT = 0x5a5a;
|
|
REG_CPM_SCRATCH = value;
|
|
REG_CPM_SCRATCH_PROT = 0xa5a5;
|
|
}
|
|
|
|
static inline void init_boot_flags(void)
|
|
{
|
|
cpm_scratch_set(0);
|
|
}
|
|
|
|
static inline bool get_boot_flag(uint32_t bit)
|
|
{
|
|
return (REG_CPM_SCRATCH & bit) != 0;
|
|
}
|
|
|
|
static inline void set_boot_flag(uint32_t bit)
|
|
{
|
|
cpm_scratch_set(REG_CPM_SCRATCH | bit);
|
|
}
|
|
|
|
static inline void clr_boot_flag(uint32_t bit)
|
|
{
|
|
cpm_scratch_set(REG_CPM_SCRATCH & ~bit);
|
|
}
|
|
|
|
static inline void set_boot_option(int opt)
|
|
{
|
|
uint32_t r = REG_CPM_SCRATCH;
|
|
r &= ~(BOOT_OPTION_MASK << BOOT_OPTION_SHIFT);
|
|
r |= (opt & BOOT_OPTION_MASK) << BOOT_OPTION_SHIFT;
|
|
cpm_scratch_set(r);
|
|
}
|
|
|
|
static inline int get_boot_option(void)
|
|
{
|
|
uint32_t r = REG_CPM_SCRATCH;
|
|
return (r >> BOOT_OPTION_SHIFT) & BOOT_OPTION_MASK;
|
|
}
|
|
|
|
#endif /* __BOOT_X1000_H__ */
|