Skip to content

Commit

Permalink
B2 changes
Browse files Browse the repository at this point in the history
  • Loading branch information
kilograham committed Sep 22, 2021
1 parent ad55537 commit ef22cd8
Show file tree
Hide file tree
Showing 14 changed files with 169 additions and 52 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
This is the B1 version of the RP2040 bootrom.
This is the B2 version of the RP2040 bootrom.

The version on the chip was built in _Debug_ mode using GCC 9.3.1 (GNU Arm Embedded Toolchain 9-2020-q2-update).

Expand Down
11 changes: 5 additions & 6 deletions bootrom/bootrom_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "hardware/sync.h"
#include "hardware/resets.h"
#include "usb_boot_device.h"
#include "resets.h"

#include "async_task.h"
#include "bootrom_crc32.h"
Expand Down Expand Up @@ -152,8 +153,7 @@ static void _usb_clock_setup() {
//
// Total postdiv of 25 means that too-fast xtal will push VCO out of
// lockable range *before* clk_sys goes out of closure (factor of 1.88)
reset_block(RESETS_RESET_PLL_SYS_BITS);
unreset_block_wait(RESETS_RESET_PLL_SYS_BITS);
reset_unreset_block_wait_noinline(RESETS_RESET_PLL_SYS_BITS);
pll_sys_hw->cs = 1u << PLL_CS_REFDIV_LSB;
pll_sys_hw->fbdiv_int = 100;
pll_sys_hw->prim =
Expand Down Expand Up @@ -183,10 +183,10 @@ void __noinline __attribute__((noreturn)) async_task_worker_thunk();

static __noinline __attribute__((noreturn)) void _usb_boot(uint32_t _usb_activity_gpio_pin_mask,
uint32_t disable_interface_mask) {
reset_block(RESETS_RESET_USBCTRL_BITS);
reset_block_noinline(RESETS_RESET_USBCTRL_BITS);
if (!running_on_fpga())
_usb_clock_setup();
unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
unreset_block_wait_noinline(RESETS_RESET_USBCTRL_BITS);

// Ensure timer and watchdog are running at approximately correct speed
// (can't switch clk_ref to xosc at this time, as we might lose ability to resus)
Expand Down Expand Up @@ -228,8 +228,7 @@ int main() {
RESETS_RESET_IO_QSPI_BITS |
RESETS_RESET_PADS_QSPI_BITS |
RESETS_RESET_TIMER_BITS;
reset_block(rst_mask);
unreset_block(rst_mask);
reset_unreset_block_wait_noinline(rst_mask);

// Workaround for behaviour of TXB0108 bidirectional level shifters on
// FPGA platform (JIRA PRJMU-726), not used on ASIC
Expand Down
72 changes: 61 additions & 11 deletions bootrom/bootrom_rt0.S
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
// - Pass core 0 control over to the main flash boot sequence

#include "hardware/regs/addressmap.h"
#include "hardware/regs/pads_bank0.h"
#include "hardware/regs/resets.h"
#include "hardware/regs/sio.h"
#include "hardware/regs/watchdog.h"
#include "hardware/regs/syscfg.h"
Expand Down Expand Up @@ -47,7 +49,7 @@ _magic:
# compatibility version (change if function table is incompatible, or functions are backwards incompatible)
.byte 1
# ROM version
.byte 2
.byte 3

.global _well_known
_well_known:
Expand Down Expand Up @@ -189,8 +191,6 @@ function_table:
.hword flash_flush_cache + 1
.byte 'C', 'X'
.hword flash_enter_cmd_xip + 1
.byte 'E', 'C'
.hword enable_clocks + 1
# end of function table marker
.hword 0

Expand Down Expand Up @@ -247,15 +247,33 @@ check_core:
// communicating with the processors).
check_rescue:
ldr r1, =(VREG_AND_CHIP_RESET_BASE + VREG_AND_CHIP_RESET_CHIP_RESET_OFFSET)
ldr r3, =(VREG_AND_CHIP_RESET_CHIP_RESET_PSM_RESTART_FLAG_BITS)
ldr r2, [r1]
tst r2, r3
beq 1f
// Acknowledge and halt
str r3, [r1]
#if VREG_AND_CHIP_RESET_CHIP_RESET_PSM_RESTART_FLAG_BITS != 0x01000000
#error
#endif
lsr r3, r2, #25
bcc 1f
// Acknowledge and halt (note we write all bits, but VREG_AND_CHIP_RESET_CHIP_RESET_PSM_RESTART_FLAG_BITS
// is the only WC bit
str r2, [r1]
b _dead
1:

disable_adc_ie:
#if RESETS_RESET_PADS_BANK0_BITS != (0x80 << 1)
#error
#endif
mov r0, #0x80
lsl r0, #1
bl unreset_block_wait_noinline

ldr r1, =PADS_BANK0_BASE + REG_ALIAS_CLR_BITS
mov r2, #PADS_BANK0_GPIO0_IE_BITS
str r2, [r1, #PADS_BANK0_GPIO26_OFFSET]
str r2, [r1, #PADS_BANK0_GPIO27_OFFSET]
str r2, [r1, #PADS_BANK0_GPIO28_OFFSET]
str r2, [r1, #PADS_BANK0_GPIO29_OFFSET]

// Check watchdog scratch for direct-boot magic numbers
// This is useful in factory test for running ARM code without accessing DAP.
// Probably also useful for imaginative software engineers
Expand Down Expand Up @@ -343,7 +361,7 @@ core_0_handshake_loop:
adr r5, core1_launch
// receive IP (0 sends us back into handshake loop)
bl send_and_then
nop ;// .. for alignment
// nop // .. for alignment
core1_launch:
// Disable SLEEPDEEP before exiting, as it affects wake latency
mov r1, #0
Expand Down Expand Up @@ -372,6 +390,35 @@ receive_and_check_zero:
beq core_0_handshake_loop
bx lr

.global reset_block_noinline
.type reset_block_noinline,%function
.thumb_func
reset_block_noinline:
ldr r1, =RESETS_BASE + REG_ALIAS_SET_BITS
str r0, [r1]
bx lr

.global reset_unreset_block_wait_noinline
.type reset_unreset_block_wait_noinline,%function
.thumb_func
reset_unreset_block_wait_noinline:
ldr r1, =RESETS_BASE + REG_ALIAS_SET_BITS
str r0, [r1]
// fall thru

.global unreset_block_wait_noinline
.type unreset_block_wait_noinline,%function
.thumb_func
unreset_block_wait_noinline:
ldr r1, =RESETS_BASE
ldr r2, =RESETS_BASE + REG_ALIAS_CLR_BITS
str r0, [r2]
1:
ldr r2, [r1, #RESETS_RESET_DONE_OFFSET]
bic r0, r2
bne 1b
bx lr

// ----------------------------------------------------------------------------
// Simple debugger trampoline for break-on-return
// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -419,7 +466,7 @@ soft_float_table:
.word mufp_fcos
.word mufp_fsin
.word mufp_ftan
.word _dead // todo use this for storage?
.word mufp_fsincos
.word mufp_fexp
.word mufp_fln

Expand Down Expand Up @@ -455,7 +502,7 @@ soft_double_table:
.word mufp_dcos
.word mufp_dsin
.word mufp_dtan
.word _dead
.word mufp_dsincos
.word mufp_dexp
.word mufp_dln

Expand Down Expand Up @@ -485,6 +532,9 @@ async_task_worker_thunk:
ldr r0, =usb_boot_stack_end
msr MSP, r0
bl async_task_worker
// async_task_worker does not return

_:

.section .bss
.align 2
Expand Down
2 changes: 1 addition & 1 deletion bootrom/info_uf2.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
UF2 Bootloader v2.0
UF2 Bootloader v3.0
Model: Raspberry Pi RP2
Board-ID: RPI-RP2
13 changes: 13 additions & 0 deletions bootrom/mufplib-double.S
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
.global mufp_dsqrt
.global mufp_dcos
.global mufp_dsin
.global mufp_dsincos
.global mufp_dtan
.global mufp_datan2
.global mufp_dexp
Expand Down Expand Up @@ -1791,6 +1792,18 @@ mufp_dsin:
bl pop_r8_r11
pop {r4-r7,r15}

.thumb_func
mufp_dsincos:
push {r4-r7,r14}
bl push_r8_r11
bl dsincos
mov r12,r0 @ save ε
bl dcos_finish
push {r0,r1}
mov r0,r12
bl dsin_finish
pop {r2,r3}
b 1b

@ unpack double θ in r0:r1, range reduce and calculate ε, cos α and sin α such that
@ θ=α+ε and |ε|≤2^-32
Expand Down
5 changes: 4 additions & 1 deletion bootrom/mufplib.S
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
.global mufp_ufix642float
.global mufp_fcos
.global mufp_fsin
.global mufp_fsincos
.global mufp_ftan
.global mufp_fatan2
.global mufp_fexp
Expand Down Expand Up @@ -481,7 +482,9 @@ cordic_vec:
b cordic_exit

.thumb_func
mufp_fsin: @ calculate sin and cos using CORDIC rotation method
mufp_fsin:
.thumb_func
mufp_fsincos: @ calculate sin and cos using CORDIC rotation method
push {r4,r5,r14}
movs r1,#24
bl mufp_float2fix @ range reduction by repeated subtraction/addition in fixed point
Expand Down
4 changes: 2 additions & 2 deletions bootrom/program_flash_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "hardware/structs/xip_ctrl.h"
#include "hardware/resets.h"
#include "program_flash_generic.h"
#include "resets.h"

// These are supported by almost any SPI flash
#define FLASHCMD_PAGE_PROGRAM 0x02
Expand Down Expand Up @@ -38,8 +39,7 @@ check_hw_layout(ssi_hw_t, spi_ctrlr0, SSI_SPI_CTRLR0_OFFSET);
void __noinline connect_internal_flash() {
// Use hard reset to force IO and pad controls to known state (don't touch
// IO_BANK0 as that does not affect XIP signals)
reset_block(RESETS_RESET_IO_QSPI_BITS | RESETS_RESET_PADS_QSPI_BITS);
unreset_block_wait(RESETS_RESET_IO_QSPI_BITS | RESETS_RESET_PADS_QSPI_BITS);
reset_unreset_block_wait_noinline(RESETS_RESET_IO_QSPI_BITS | RESETS_RESET_PADS_QSPI_BITS);

// Then mux XIP block onto internal QSPI flash pads
io_rw_32 *iobank1 = (io_rw_32 *) IO_QSPI_BASE;
Expand Down
16 changes: 16 additions & 0 deletions bootrom/resets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

#ifndef _RESETS_H
#define _RESETS_H

#include "pico/types.h"

void reset_block_noinline(uint32_t mask);
void unreset_block_wait_noinline(uint32_t mask);
void reset_unreset_block_wait_noinline(uint32_t mask);

#endif
8 changes: 3 additions & 5 deletions bootrom/usb_boot_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ char serial_number_string[13];
// todo make descriptor strings should probably belong/come from the configs
static char *descriptor_strings[] =
{
"",
"Raspberry Pi",
"RP2 Boot",
serial_number_string
Expand Down Expand Up @@ -164,11 +165,8 @@ uint32_t msc_get_serial_number32() {
}

const char *_get_descriptor_string(uint index) {
if (index <= count_of(descriptor_strings)) {
return descriptor_strings[index - 1];
} else {
return "";
}
if (index >= count_of(descriptor_strings)) index = 0;
return descriptor_strings[index];
}


Expand Down
26 changes: 22 additions & 4 deletions test/tc_rom_double.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ struct mufp_funcs {
double (*mufp_dcos)(double);
double (*mufp_dsin)(double);
double (*mufp_dtan)(double);
// since float doesn't use this slot, we don't either
uint32_t _not_fatan2; // double (*mufp_datan2)(double, double);
double (*v3_mufp_dsincos)(double);
double (*mufp_dexp)(double);
double (*mufp_dln)(double);

Expand Down Expand Up @@ -235,7 +234,17 @@ int __attribute__((naked)) dcmp_from_dcmp_flags(double a, double b, int (*dmcp_f
);
}

#define check_dcmp_flags(a,b) check_int(dcmp(a, b), dcmp_from_dcmp_flags(a, b, mufp_funcs->mufp_dcmp)) // dcmp is dcmp_flags now
double __attribute__((naked)) call_dsincos(double v, double *cout, double (*func)(double)) {
asm(
"push {r2, r4, lr}\n"
"blx r3\n"
"pop {r4}\n"
"stmia r4!, {r2, r3}\n"
"pop {r4, pc}\n"
);
}

#define check_dcmp_flags(a,b) check_int(dcmp(a, b), dcmp_from_dcmp_flags(a, b, (void (*)(double,double))mufp_funcs->mufp_dcmp)) // dcmp is dcmp_flags now
#define check_dcmp_fast_flags(a,b) check_int(dcmp_fast(a, b), dcmp_from_dcmp_flags(a, b, mufp_funcs->mufp_dcmp_fast_flags))

int main()
Expand Down Expand Up @@ -522,6 +531,15 @@ int main()
check_double_fn1(double2float, 3.0e68);
check_double_fn1(double2float, -3.0e68);

if (rom_version >= 3) {
for(double a = -0.3f; a<7.f; a += 0.137) {
double s = mufp_funcs->mufp_dsin(a);
double c = mufp_funcs->mufp_dcos(a);
double co=0;
double so = call_dsincos(a, &co, mufp_funcs->v3_mufp_dsincos);
ASSERT(so == s && co == c);
}
}
printf("DOUBLE OK\n");
return 0;
return 0;
}
23 changes: 21 additions & 2 deletions test/tc_rom_float.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct mufp_funcs {
float (*mufp_fcos)(float);
float (*mufp_fsin)(float);
float (*mufp_ftan)(float);
uint32_t _broken_fatan2; // float (*mufp_fatan2)(float, float);
float (*v3_mufp_fsincos)(float);
float (*mufp_fexp)(float);
float (*mufp_fln)(float);

Expand Down Expand Up @@ -232,7 +232,17 @@ int __attribute__((naked)) fcmp_from_fcmp_flags(float a, float b, int (*fmcp_fla
);
}

#define check_fcmp_flags(a,b) check_int(fcmp(a, b), fcmp_from_fcmp_flags(a, b, mufp_funcs->mufp_fcmp)) // f_cmp is f_cmp_flags now
float __attribute__((naked)) call_fsincos(float v, float *cout, float (*func)(float)) {
asm(
"push {r1, lr}\n"
"blx r2\n"
"pop {r2}\n"
"str r1, [r2]\n"
"pop {pc}\n"
);
}

#define check_fcmp_flags(a,b) check_int(fcmp(a, b), fcmp_from_fcmp_flags(a, b, (void (*)(float, float))mufp_funcs->mufp_fcmp)) // f_cmp is f_cmp_flags now
#define check_fcmp_fast_flags(a,b) check_int(fcmp_fast(a, b), fcmp_from_fcmp_flags(a, b, mufp_funcs->mufp_fcmp_fast_flags))

int main()
Expand Down Expand Up @@ -501,6 +511,15 @@ int main()
check_float_fn1(float2double, -0.f);
}

if (rom_version >= 3) {
for(float a = -0.3f; a<7.f; a += 0.137) {
float s = mufp_funcs->mufp_fsin(a);
float c = mufp_funcs->mufp_fcos(a);
float co=0;
float so = call_fsincos(a, &co, mufp_funcs->v3_mufp_fsincos);
ASSERT(so == s && co == c);
}
}
printf("FLOAT OK\n");
return 0;
}
Loading

0 comments on commit ef22cd8

Please sign in to comment.