Import of the watch repository from Pebble

This commit is contained in:
Matthieu Jeanson 2024-12-12 16:43:03 -08:00 committed by Katharine Berry
commit 3b92768480
10334 changed files with 2564465 additions and 0 deletions

View file

@ -0,0 +1,26 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "flash_region/filesystem_regions.h"
#include "util/size.h"
void filesystem_regions_erase_all(void) {
for (unsigned int i = 0; i < ARRAY_LENGTH(s_region_list); i++) {
flash_region_erase_optimal_range_no_watchdog(s_region_list[i].start, s_region_list[i].start,
s_region_list[i].end, s_region_list[i].end);
}
}

View file

@ -0,0 +1,86 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "flash_region.h"
#include <stdint.h>
//! @file filesystem_regions.h
//!
//! This file describes the various regions that make up our filesystem. For historical reasons,
//! our filesystem is not one contiguous space in flash and is instead broken up across multiple
//! regions.
//! Individual filesystem region
typedef struct FSRegion {
uint32_t start;
uint32_t end;
} FSRegion;
// Note: Different platforms use different flash layouts (see flash_region/flash_region.h for more
// info).
//
// Our newer platforms only have one contiguous filesystem region which you can find below. Some
// legacy platforms (i.e Pebble OG and Pebble Steel) had flash regions added to the filesystem over
// time and are thus non-contiguous. For layouts with more than one region you will find their
// header included below.
#if PLATFORM_TINTIN
#include "filesystem_regions_n25q.h"
#else
// Typical single region filesystem layout
#define FILE_SYSTEM_REGIONS(MACRO_OPERATOR) \
MACRO_OPERATOR(FLASH_REGION_FILESYSTEM_BEGIN, FLASH_REGION_FILESYSTEM_END)
#endif
// Notes:
// In this file we check that individual region entries are sector aligned at the beginning and
// the end because the filesystem only performs _sector_ erases.
//
// To accomplish this at compile time we use a tiny bit of macro-fu. For each platform we expect
// a 'FILE_SYSTEM_REGIONS(MACRO_OPERATOR)' definition. Within the macro definition, each
// FSRegion's '.start' and '.end' is wrapped within a 'MACRO_OPERATOR'
//
// The MACRO_OPERATOR argument is simply another macro that operates on the FLASH_SYSTEM_REGIONS
// list. This allows us to go through the list once to check layouts as a static assert (See
// FILE_SYSTEM_LAYOUT_CHECK) and then go through the list to build the s_region_list struct (See
// FILE_SYSTEM_FS_REGION_ENTRY_CONSTRUCTOR)
//
// Bonus Fun fact: 'analytics_metric_table.h' uses this same strategy to turn our analytics list
// into an enum, switch case statement, and AnalyticsMetricDataType array.
#define FILE_SYSTEM_LAYOUT_CHECK(s, e) \
_Static_assert((s % SECTOR_SIZE_BYTES) == 0, "Filesystem region start not sector aligned"); \
_Static_assert((e % SECTOR_SIZE_BYTES) == 0, "Filesystem end region not sector aligned"); \
#define FILE_SYSTEM_FS_REGION_ENTRY_CONSTRUCTOR(s, e) { .start = s, .end = e },
// Make sure all the filesystem regions are flash sector aligned
FILE_SYSTEM_REGIONS(FILE_SYSTEM_LAYOUT_CHECK)
// Build the flash region list
static const FSRegion s_region_list[] = {
FILE_SYSTEM_REGIONS(FILE_SYSTEM_FS_REGION_ENTRY_CONSTRUCTOR)
};
//! Erase all the regions that belong to our filesystem. Note that this is just a flash erase,
//! if you want to leave behind a fully erased and initialized filesystem you should be using
//! pfs_format instead.
void filesystem_regions_erase_all(void);

View file

@ -0,0 +1,41 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
//! @file filesystem_regions_n25q.h
//!
//! Flash regions used for the filesystem used by the serial flash chip that we're using in
//! Tintin/Bianca. Only included by core/flash_region/filesystem_regions.c
#if !RECOVERY_FW
#define FILE_SYSTEM_REGIONS(MACRO_OPERATOR) \
MACRO_OPERATOR(FLASH_REGION_FILESYSTEM_BEGIN, FLASH_REGION_FILESYSTEM_END) \
MACRO_OPERATOR(FLASH_REGION_FILESYSTEM_2_BEGIN, FLASH_REGION_FILESYSTEM_2_END) \
MACRO_OPERATOR(FLASH_REGION_FILESYSTEM_3_BEGIN, FLASH_REGION_FILESYSTEM_3_END) \
MACRO_OPERATOR(FLASH_REGION_FILESYSTEM_4_BEGIN, FLASH_REGION_FILESYSTEM_4_END) \
MACRO_OPERATOR(FLASH_REGION_EXTRA_FILESYSTEM_BEGIN, FLASH_REGION_EXTRA_FILESYSTEM_END) \
MACRO_OPERATOR(FLASH_REGION_FILESYSTEM_5_BEGIN, FLASH_REGION_FILESYSTEM_5_END)
#else // Same as normal fw except there is one extra region to erase
#define FILE_SYSTEM_REGIONS(MACRO_OPERATOR) \
MACRO_OPERATOR(FLASH_REGION_FILESYSTEM_BEGIN, FLASH_REGION_FILESYSTEM_END) \
MACRO_OPERATOR(FLASH_REGION_FILESYSTEM_2_BEGIN, FLASH_REGION_FILESYSTEM_2_END) \
MACRO_OPERATOR(FLASH_REGION_FILESYSTEM_3_BEGIN, FLASH_REGION_FILESYSTEM_3_END) \
MACRO_OPERATOR(FLASH_REGION_FILESYSTEM_4_BEGIN, FLASH_REGION_FILESYSTEM_4_END) \
MACRO_OPERATOR(FLASH_REGION_EXTRA_FILESYSTEM_BEGIN, FLASH_REGION_EXTRA_FILESYSTEM_END) \
MACRO_OPERATOR(FLASH_REGION_FILESYSTEM_5_BEGIN, FLASH_REGION_FILESYSTEM_5_END) \
MACRO_OPERATOR(FLASH_REGION_UNUSED0_BEGIN, FLASH_REGION_UNUSED0_END)
#endif

View file

@ -0,0 +1,117 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "flash_region.h"
#include "drivers/flash.h"
#include "drivers/task_watchdog.h"
#include "kernel/util/sleep.h"
#include "system/logging.h"
#include "system/passert.h"
#include <inttypes.h>
//! Do some upkeep in between erases to keep the rest of the system stable since erases block
//! the current task for so long.
//!
//! @param erase_count[in, out] Counter variable to track how many times we've run this upkeep
// function
//! @param feed_watchdog Whether we should feed the task_watchdog for the current task or not
static void prv_erase_upkeep(int *erase_count, bool feed_watchdog) {
(*erase_count)++;
if ((*erase_count %= 2) == 0) {
// Sleep if this is the second time in a row calling erase (sub)sector.
// FIXME: We could check and see if we are starving tasks and only force a
// context switch for that case
psleep((SECTOR_SIZE_BYTES > (64 * 1024)) ? 20 : 4);
}
if (feed_watchdog) {
task_watchdog_bit_set(pebble_task_get_current());
}
}
static void prv_erase_optimal_range(uint32_t min_start, uint32_t max_start,
uint32_t min_end, uint32_t max_end, bool feed_watchdog) {
PBL_LOG(LOG_LEVEL_DEBUG, "flash_region_erase_optimal_range, 0x%"PRIx32" 0x%"PRIx32" 0x%"PRIx32" 0x%"PRIx32,
min_start, max_start, min_end, max_end);
PBL_ASSERTN(((min_start & (~SUBSECTOR_ADDR_MASK)) == 0) &&
((max_end & (~SUBSECTOR_ADDR_MASK)) == 0) &&
(min_start <= max_start) &&
(max_start <= min_end) &&
(min_end <= max_end));
// We want to erase the sector that starts immediately below max_start but after min_start. If no sector
// boundary exists between the two, we need to start erasing sectors after min_start and backfill with
// subsector erases.
int32_t sector_start = (max_start & SECTOR_ADDR_MASK);
int32_t subsector_start = (max_start & SUBSECTOR_ADDR_MASK);
if (sector_start < (int32_t) min_start) {
sector_start += SECTOR_SIZE_BYTES;
}
// We want to erase ending after min_end but before max_end. If that ends running past the end of max_end,
// we need to erase starting with the sector before and fill in with subsector erases.
int32_t sector_end = ((min_end - 1) & SECTOR_ADDR_MASK) + SECTOR_SIZE_BYTES;
int32_t subsector_end = ((min_end - 1) & SUBSECTOR_ADDR_MASK) + SUBSECTOR_SIZE_BYTES;
if (sector_end > (int32_t) max_end) {
sector_end -= SECTOR_SIZE_BYTES;
}
int erase_count = 0;
// Do the upkeep immediately just in case we've spent awhile running without feeding the
// watchdog before doing this erase operation.
prv_erase_upkeep(&erase_count, feed_watchdog);
if (sector_start < sector_end) {
// Now erase the leading subsectors...
for (int32_t i = subsector_start; i < sector_start; i += SUBSECTOR_SIZE_BYTES) {
flash_erase_subsector_blocking(i);
prv_erase_upkeep(&erase_count, feed_watchdog);
}
// Erase the full sectors...
for (int32_t i = sector_start; i < sector_end; i += SECTOR_SIZE_BYTES) {
flash_erase_sector_blocking(i);
prv_erase_upkeep(&erase_count, feed_watchdog);
}
// Erase the trailing subsectors
for (int32_t i = sector_end; i < subsector_end; i += SUBSECTOR_SIZE_BYTES) {
flash_erase_subsector_blocking(i);
prv_erase_upkeep(&erase_count, feed_watchdog);
}
} else {
// Can't erase any full sectors, just erase subsectors the whole way.
for (int32_t i = subsector_start; i < subsector_end; i += SUBSECTOR_SIZE_BYTES) {
flash_erase_subsector_blocking(i);
prv_erase_upkeep(&erase_count, feed_watchdog);
}
}
}
void flash_region_erase_optimal_range(uint32_t min_start, uint32_t max_start,
uint32_t min_end, uint32_t max_end) {
prv_erase_optimal_range(min_start, max_start, min_end, max_end, false /* feed_watchdog */);
}
void flash_region_erase_optimal_range_no_watchdog(uint32_t min_start, uint32_t max_start,
uint32_t min_end, uint32_t max_end) {
prv_erase_optimal_range(min_start, max_start, min_end, max_end, true /* feed_watchdog */);
}

View file

@ -0,0 +1,58 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#if PLATFORM_TINTIN
// v2_0 and v1_5 have 8MB flash chips instead of 4MB. In the following definition,
// BOARD_NOR_FLASH_SIZE is set to allow 6MB of the flash chip to be used. The extra 2MB tacked
// onto the end will be used for the filesystem and is being added to help with storing large
// language packs (ex. Chinese). If the entire 8MB needs to be used, this variable will have to
// be changed. Migrations are likely as well.
//
// On watches with only 4MB of flash, the region will have a size of zero and be ignored by the
// fileystem.
#if defined(BOARD_V2_0) || defined(BOARD_V1_5) || defined(LARGE_SPI_FLASH)
#define BOARD_NOR_FLASH_SIZE 0x600000
#else
#define BOARD_NOR_FLASH_SIZE 0x400000
#endif
#include "flash_region_n25q.h"
#elif PLATFORM_SILK
#include "flash_region_mx25u.h"
#elif PLATFORM_CALCULUS || PLATFORM_ROBERT
#include "flash_region_mt25q.h"
#elif PLATFORM_SNOWY || PLATFORM_SPALDING
#include "flash_region_s29vs.h"
#endif
// NOTE: The following functions are deprecated! New code should use the
// asynchronous version, flash_erase_optimal_range, in flash.h.
//! Erase at least (max_start, min_end) but no more than (min_start, max_end) using as few erase operations
//! as possible.
//! (min_start, max_end) must be both 4kb aligned, as that's the smallest unit that we can erase.
void flash_region_erase_optimal_range(uint32_t min_start, uint32_t max_start,
uint32_t min_end, uint32_t max_end);
//! The same as flash_region_erase_optimal_range but first disables the task watchdog for the
//! current task.
void flash_region_erase_optimal_range_no_watchdog(uint32_t min_start, uint32_t max_start,
uint32_t min_end, uint32_t max_end);

View file

@ -0,0 +1,37 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
enum {
#define FLASH_REGION_LIST(name, size, arg) FlashRegion_##name,
FLASH_REGION_DEF(FLASH_REGION_LIST, NULL)
FlashRegion__COUNT
};
#define FLASH_REGION_ADDR_HELPER(name, size, tgt) \
+ (FlashRegion_##name < (tgt) ? (size) : 0)
// These macros add up all the sizes of the flash regions that come before (and including in the
// case of the _END_ADDR macro) the specified one to determine the proper flash address value.
#define FLASH_REGION_START_ADDR(region) \
((0) FLASH_REGION_DEF(FLASH_REGION_ADDR_HELPER, FlashRegion_##region))
#define FLASH_REGION_END_ADDR(region) \
((0) FLASH_REGION_DEF(FLASH_REGION_ADDR_HELPER, FlashRegion_##region + 1))
// Checks that all regions are a multiple of the specified size (usually sector or subsector size)
#define FLASH_REGION_SIZE_CHECK_HELPER(name, size, arg) \
&& ((size) % (arg) == 0)
#define FLASH_REGION_SIZE_CHECK(size) \
_Static_assert((1) FLASH_REGION_DEF(FLASH_REGION_SIZE_CHECK_HELPER, size), "Invalid region size");

View file

@ -0,0 +1,88 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#define PAGE_SIZE_BYTES (0x100)
#define SECTOR_SIZE_BYTES (0x10000)
#define SECTOR_ADDR_MASK (~(SECTOR_SIZE_BYTES - 1))
#define SUBSECTOR_SIZE_BYTES (0x1000)
#define SUBSECTOR_ADDR_MASK (~(SUBSECTOR_SIZE_BYTES - 1))
// A bit of preprocessor magic to help with automatically calculating flash region addresses
//////////////////////////////////////////////////////////////////////////////
#define FLASH_REGION_DEF(MACRO, arg) \
MACRO(FIRMWARE_SCRATCH, 0x200000 /* 2048k */, arg) \
MACRO(SYSTEM_RESOURCES_BANK_0, 0x100000 /* 1024k */, arg) \
MACRO(SYSTEM_RESOURCES_BANK_1, 0x100000 /* 1024k */, arg) \
MACRO(SAFE_FIRMWARE, 0x080000 /* 512k */, arg) \
MACRO(DEBUG_DB, 0x020000 /* 128k */, arg) \
MACRO(MFG_INFO, 0x020000 /* 128k */, arg) \
MACRO(FILESYSTEM, 0xB30000 /* 11456k */, arg) \
MACRO(RSVD, 0x00F000 /* 60k */, arg) \
MACRO(SHARED_PRF_STORAGE, 0x001000 /* 4k */, arg)
#include "flash_region_def_helper.h"
// Flash region _BEGIN and _END addresses
//////////////////////////////////////////////////////////////////////////////
#define FLASH_REGION_FIRMWARE_SCRATCH_BEGIN FLASH_REGION_START_ADDR(FIRMWARE_SCRATCH)
#define FLASH_REGION_FIRMWARE_SCRATCH_END FLASH_REGION_END_ADDR(FIRMWARE_SCRATCH)
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_0_BEGIN FLASH_REGION_START_ADDR(SYSTEM_RESOURCES_BANK_0)
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_0_END FLASH_REGION_END_ADDR(SYSTEM_RESOURCES_BANK_0)
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_1_BEGIN FLASH_REGION_START_ADDR(SYSTEM_RESOURCES_BANK_1)
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_1_END FLASH_REGION_END_ADDR(SYSTEM_RESOURCES_BANK_1)
#define FLASH_REGION_SAFE_FIRMWARE_BEGIN FLASH_REGION_START_ADDR(SAFE_FIRMWARE)
#define FLASH_REGION_SAFE_FIRMWARE_END FLASH_REGION_END_ADDR(SAFE_FIRMWARE)
#define FLASH_REGION_DEBUG_DB_BEGIN FLASH_REGION_START_ADDR(DEBUG_DB)
#define FLASH_REGION_DEBUG_DB_END FLASH_REGION_END_ADDR(DEBUG_DB)
#define FLASH_DEBUG_DB_BLOCK_SIZE SUBSECTOR_SIZE_BYTES
#define FLASH_REGION_FILESYSTEM_BEGIN FLASH_REGION_START_ADDR(FILESYSTEM)
#define FLASH_REGION_FILESYSTEM_END FLASH_REGION_END_ADDR(FILESYSTEM)
#define FLASH_FILESYSTEM_BLOCK_SIZE 0x2000 // 8k
#define FLASH_REGION_SHARED_PRF_STORAGE_BEGIN FLASH_REGION_START_ADDR(SHARED_PRF_STORAGE)
#define FLASH_REGION_SHARED_PRF_STORAGE_END FLASH_REGION_END_ADDR(SHARED_PRF_STORAGE)
#define FLASH_REGION_MFG_INFO_BEGIN FLASH_REGION_START_ADDR(MFG_INFO)
#define FLASH_REGION_MFG_INFO_END FLASH_REGION_END_ADDR(MFG_INFO)
#define BOARD_NOR_FLASH_SIZE FLASH_REGION_START_ADDR(_COUNT)
// Static asserts to make sure everything worked out
//////////////////////////////////////////////////////////////////////////////
// make sure all the sizes are multiples of the subsector size (4k)
FLASH_REGION_SIZE_CHECK(SUBSECTOR_SIZE_BYTES)
// make sure the shared PRF storage is within the last 64k sector so we can protect them.
_Static_assert(FLASH_REGION_SHARED_PRF_STORAGE_BEGIN >= BOARD_NOR_FLASH_SIZE - SECTOR_SIZE_BYTES,
"Shared PRF storage should be within the last 64k of flash");
// make sure the total size is what we expect (16MB for robert)
_Static_assert(BOARD_NOR_FLASH_SIZE == 0x1000000, "Flash size should be 16MB");

View file

@ -0,0 +1,90 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#define PAGE_SIZE_BYTES (0x100)
#define SECTOR_SIZE_BYTES (0x10000)
#define SECTOR_ADDR_MASK (~(SECTOR_SIZE_BYTES - 1))
#define SUBSECTOR_SIZE_BYTES (0x1000)
#define SUBSECTOR_ADDR_MASK (~(SUBSECTOR_SIZE_BYTES - 1))
// A bit of preprocessor magic to help with automatically calculating flash region addresses
//////////////////////////////////////////////////////////////////////////////
#define FLASH_REGION_DEF(MACRO, arg) \
MACRO(FIRMWARE_SCRATCH, 0x100000 /* 1024k */, arg) /* 0x0 - 0x100000 */ \
MACRO(SYSTEM_RESOURCES_BANK_0, 0x080000 /* 512K */, arg) /* 0x100000 - 0x180000 */ \
MACRO(SYSTEM_RESOURCES_BANK_1, 0x080000 /* 512K */, arg) /* 0x180000 - 0x200000 */ \
MACRO(SAFE_FIRMWARE, 0x080000 /* 512k */, arg) /* 0x200000 - 0x280000 */ \
MACRO(DEBUG_DB, 0x020000 /* 128k */, arg) /* 0x280000 - 0x2A0000 */ \
MACRO(FILESYSTEM, 0x550000 /* 5440k */, arg) /* 0x2A0000 - 0x7F0000 */ \
MACRO(RSVD, 0x00E000 /* 56k */, arg) /* 0x7F0000 - 0x7FE000 */ \
MACRO(SHARED_PRF_STORAGE, 0x001000 /* 4k */, arg) /* 0x7FE000 - 0x7FF000 */ \
MACRO(MFG_INFO, 0x001000 /* 4k */, arg) /* 0x7FF000 - 0x800000 */
#include "flash_region_def_helper.h"
// Flash region _BEGIN and _END addresses
//////////////////////////////////////////////////////////////////////////////
#define FLASH_REGION_FIRMWARE_SCRATCH_BEGIN FLASH_REGION_START_ADDR(FIRMWARE_SCRATCH)
#define FLASH_REGION_FIRMWARE_SCRATCH_END FLASH_REGION_END_ADDR(FIRMWARE_SCRATCH)
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_0_BEGIN FLASH_REGION_START_ADDR(SYSTEM_RESOURCES_BANK_0)
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_0_END FLASH_REGION_END_ADDR(SYSTEM_RESOURCES_BANK_0)
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_1_BEGIN FLASH_REGION_START_ADDR(SYSTEM_RESOURCES_BANK_1)
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_1_END FLASH_REGION_END_ADDR(SYSTEM_RESOURCES_BANK_1)
#define FLASH_REGION_SAFE_FIRMWARE_BEGIN FLASH_REGION_START_ADDR(SAFE_FIRMWARE)
#define FLASH_REGION_SAFE_FIRMWARE_END FLASH_REGION_END_ADDR(SAFE_FIRMWARE)
#define FLASH_REGION_DEBUG_DB_BEGIN FLASH_REGION_START_ADDR(DEBUG_DB)
#define FLASH_REGION_DEBUG_DB_END FLASH_REGION_END_ADDR(DEBUG_DB)
#define FLASH_DEBUG_DB_BLOCK_SIZE SUBSECTOR_SIZE_BYTES
#define FLASH_REGION_FILESYSTEM_BEGIN FLASH_REGION_START_ADDR(FILESYSTEM)
#define FLASH_REGION_FILESYSTEM_END FLASH_REGION_END_ADDR(FILESYSTEM)
#define FLASH_FILESYSTEM_BLOCK_SIZE SUBSECTOR_SIZE_BYTES
#define FLASH_REGION_SHARED_PRF_STORAGE_BEGIN FLASH_REGION_START_ADDR(SHARED_PRF_STORAGE)
#define FLASH_REGION_SHARED_PRF_STORAGE_END FLASH_REGION_END_ADDR(SHARED_PRF_STORAGE)
#define FLASH_REGION_MFG_INFO_BEGIN FLASH_REGION_START_ADDR(MFG_INFO)
#define FLASH_REGION_MFG_INFO_END FLASH_REGION_END_ADDR(MFG_INFO)
#define BOARD_NOR_FLASH_SIZE FLASH_REGION_START_ADDR(_COUNT)
// Static asserts to make sure everything worked out
//////////////////////////////////////////////////////////////////////////////
// make sure all the sizes are multiples of the subsector size (4k)
FLASH_REGION_SIZE_CHECK(SUBSECTOR_SIZE_BYTES)
// make sure the PRF and MFG regions are within the last 64k sector so we can protect them.
_Static_assert(FLASH_REGION_SHARED_PRF_STORAGE_BEGIN >= BOARD_NOR_FLASH_SIZE - SECTOR_SIZE_BYTES,
"Shared PRF storage should be within the last 64k of flash");
_Static_assert(FLASH_REGION_MFG_INFO_BEGIN >= BOARD_NOR_FLASH_SIZE - SECTOR_SIZE_BYTES,
"MFG info should be within the last 64k of flash");
// make sure the total size is what we expect (8mb for silk)
_Static_assert(BOARD_NOR_FLASH_SIZE == 0x800000, "Flash size should be 8mb");

View file

@ -0,0 +1,83 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#define SECTOR_SIZE_BYTES 0x10000
#define SECTOR_ADDR_MASK (~(SECTOR_SIZE_BYTES - 1))
#define SUBSECTOR_SIZE_BYTES 0x1000
#define SUBSECTOR_ADDR_MASK (~(SUBSECTOR_SIZE_BYTES - 1))
#define FLASH_FILESYSTEM_BLOCK_SIZE SUBSECTOR_SIZE_BYTES
// Filesystem layout
///////////////////////////////////////
// Scratch space for firmware images (normal and recovery).
// We assume this is 64k aligned...
#define FLASH_REGION_FIRMWARE_SCRATCH_BEGIN 0x0
#define FLASH_REGION_FIRMWARE_SCRATCH_END 0x80000 // 512k
// Formerly FLASH_REGION_APP_BEGIN
#define FLASH_REGION_FILESYSTEM_3_BEGIN 0x80000
#define FLASH_REGION_FILESYSTEM_3_END 0x100000 // 512k
// Formerly REGISTRY_FLASH
// Use one sector for the shared prf storage
#define FLASH_REGION_SHARED_PRF_STORAGE_BEGIN 0x100000
#define FLASH_REGION_SHARED_PRF_STORAGE_END 0x110000 // 64k
// Use one sector to store the factory settings registry
#define FACTORY_REGISTRY_FLASH_BEGIN 0x110000 //
#define FACTORY_REGISTRY_FLASH_END 0x120000 // 64k
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_0_BEGIN 0x120000
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_0_END 0x160000 // 256k
// Formerly part of the 640k of data-logging, which was added to the filesystem as FILESYSTEM_5
// Reserved a couple sectors because it's always nice to have a couple free.
#define FLASH_REGION_UNUSED0_BEGIN 0x160000
#define FLASH_REGION_UNUSED0_END 0x180000 // 128k
#define FLASH_REGION_FILESYSTEM_5_BEGIN 0x180000
#define FLASH_REGION_FILESYSTEM_5_END 0x200000 // 512k
#define FLASH_REGION_SAFE_FIRMWARE_BEGIN 0x200000
#define FLASH_REGION_SAFE_FIRMWARE_END 0x280000 // 512k
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_1_BEGIN 0x280000
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_1_END 0x2c0000 // 256k
// Formerly FLASH_REGION_RESERVED_BEGIN
#define FLASH_REGION_FILESYSTEM_2_BEGIN 0x2c0000 //64k
#define FLASH_REGION_FILESYSTEM_2_END 0x2d0000
#define FLASH_REGION_FILESYSTEM_BEGIN 0x2d0000
#define FLASH_REGION_FILESYSTEM_END 0x320000 // 320k
// Formerly FLASH_REGION_APP_RESOURCES_BEGIN
#define FLASH_REGION_FILESYSTEM_4_BEGIN 0x320000
#define FLASH_REGION_FILESYSTEM_4_END 0x3e0000 // 768k
#define FLASH_REGION_DEBUG_DB_BEGIN 0x3e0000
#define FLASH_REGION_DEBUG_DB_END 0x400000 // 128k
#define FLASH_DEBUG_DB_BLOCK_SIZE SECTOR_SIZE_BYTES
#define FLASH_REGION_EXTRA_FILESYSTEM_BEGIN 0x400000
#define FLASH_REGION_EXTRA_FILESYSTEM_END BOARD_NOR_FLASH_SIZE
// 0x400000 is the end of the SPI flash address space.

View file

@ -0,0 +1,88 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#define SECTOR_SIZE_BYTES 0x20000
#define SECTOR_ADDR_MASK (~(SECTOR_SIZE_BYTES - 1))
#define FLASH_FILESYSTEM_BLOCK_SIZE 0x2000
#define SUBSECTOR_SIZE_BYTES 0x20000
#define SUBSECTOR_ADDR_MASK (~(SUBSECTOR_SIZE_BYTES - 1))
// FMC_BANK_1_BASE_ADDRESS
#define FLASH_MEMORY_MAPPABLE_ADDRESS 0x60000000
#define FLASH_MEMORY_MAPPABLE_SIZE BOARD_NOR_FLASH_SIZE
// Filesystem layout
///////////////////////////////////////
// Space for our flash logs
// NOTE: This range of memory is actually in the special "bottom boot" area of our flash chip
// where the erase sectors are smaller (32k instead of 128k everywhere else).
#define FLASH_REGION_DEBUG_DB_BEGIN 0x0
#define FLASH_REGION_DEBUG_DB_END 0x20000 // 128k
#define FLASH_DEBUG_DB_BLOCK_SIZE BOTTOM_BOOT_SECTOR_SIZE
#define BOTTOM_BOOT_REGION_END 0x20000 // 128k
#define BOTTOM_BOOT_SECTOR_SIZE 0x8000 // 32k
// Regions after this point are in standard, 128kb sized sectors.
// 640kb gap here. We should save some space for non-filesystem things. It also aligns the
// subsequent sectors nicely.
// 1 128kb sector for storing bluetooth parings which are shared between normal fw and prf
#define FLASH_REGION_SHARED_PRF_STORAGE_BEGIN 0x0C0000
#define FLASH_REGION_SHARED_PRF_STORAGE_END 0x0E0000
// 1 128kb sector for storing mfg info, see fw/mfg/snowy/mfg_info.c
#define FLASH_REGION_MFG_INFO_BEGIN 0x0E0000
#define FLASH_REGION_MFG_INFO_END 0x100000
// Scratch space for firmware images (normal and recovery).
#define FLASH_REGION_FIRMWARE_SCRATCH_BEGIN 0x100000
#define FLASH_REGION_FIRMWARE_SCRATCH_END 0x200000 // 1024k
#define FLASH_REGION_SAFE_FIRMWARE_BEGIN 0x200000
#define FLASH_REGION_SAFE_FIRMWARE_END 0x300000 // 1024k
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_0_BEGIN 0x300000
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_0_END 0x380000 // 512k
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_1_BEGIN 0x380000
#define FLASH_REGION_SYSTEM_RESOURCES_BANK_1_END 0x400000 // 512k
#define FLASH_REGION_FILESYSTEM_BEGIN 0x0400000
#define FLASH_REGION_FILESYSTEM_END 0x1000000 // 8mb+, aka the rest!
// Constants used for testing flash interface
// NOTE: This purposely overlaps the file system region since the flash test requires a non-critical
// region to operate on. Data in this region will get corrupted and will not get restored after the
// test runs. Any data in this region will have to be manually restored or reinitialized.
#define FLASH_TEST_ADDR_START 0x0800000 // 8MB
#define FLASH_TEST_ADDR_END 0x1000000 // 16MB
#define FLASH_TEST_ADDR_MSK 0x1FFFFFF // test all bits in the 16MB range
#define BOARD_NOR_FLASH_SIZE 0x1000000
#if ((FLASH_REGION_FILESYSTEM_BEGIN > FLASH_TEST_ADDR_START) || (FLASH_REGION_FILESYSTEM_END < FLASH_TEST_ADDR_END))
#error "ERROR: Flash Test space not withing expected range"
#endif
// 0x1000000 is the end of the SPI flash address space.