mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-16 09:54:35 +00:00
Merge branch '2024-03-02-assorted-updates' into next
- Assorted MediaTek, ASPEED, xenguest, s5p4418 and qemu-arm fixes - Assorted test fixes/updates/additions. - A few bootstd/related fixes. - Remove common.h from some files - Drop reiserfs - A few other assorted fixes throughout the tree.
This commit is contained in:
commit
bd465ada0e
69 changed files with 551 additions and 2056 deletions
3
Makefile
3
Makefile
|
@ -1831,7 +1831,8 @@ ENV_FILE := $(if $(ENV_SOURCE_FILE),$(ENV_FILE_CFG),$(wildcard $(ENV_FILE_BOARD)
|
|||
quiet_cmd_gen_envp = ENVP $@
|
||||
cmd_gen_envp = \
|
||||
if [ -s "$(ENV_FILE)" ]; then \
|
||||
$(CPP) -P $(CFLAGS) -x assembler-with-cpp -D__ASSEMBLY__ \
|
||||
$(CPP) -P $(CFLAGS) -x assembler-with-cpp -undef \
|
||||
-D__ASSEMBLY__ \
|
||||
-D__UBOOT_CONFIG__ \
|
||||
-I . -I include -I $(srctree)/include \
|
||||
-include linux/kconfig.h -include include/config.h \
|
||||
|
|
|
@ -699,15 +699,6 @@ config TARGET_BCMNS
|
|||
ARMv7 Cortex-A9 SoC family including BCM4708, BCM47094,
|
||||
BCM5301x etc.
|
||||
|
||||
config TARGET_BCMNS2
|
||||
bool "Support Broadcom Northstar2"
|
||||
select ARM64
|
||||
select GPIO_EXTRA_HEADER
|
||||
help
|
||||
Support for Broadcom Northstar 2 SoCs. NS2 is a quad-core 64-bit
|
||||
ARMv8 Cortex-A57 processors targeting a broad range of networking
|
||||
applications.
|
||||
|
||||
config TARGET_BCMNS3
|
||||
bool "Support Broadcom NS3"
|
||||
select ARM64
|
||||
|
|
|
@ -2,5 +2,8 @@
|
|||
#
|
||||
# (C) Copyright 2016 Nexell
|
||||
# Hyunseok, Jung <hsjung@nexell.co.kr>
|
||||
#
|
||||
# Copyright (C) 2023 Stefan Bosch <stefan_b@posteo.net>
|
||||
|
||||
obj-y += cpu.o
|
||||
obj-y += relocate.o
|
||||
|
|
24
arch/arm/cpu/armv7/s5p4418/relocate.S
Normal file
24
arch/arm/cpu/armv7/s5p4418/relocate.S
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* relocate - S5P4418 specific relocation for ARM U-Boot
|
||||
*
|
||||
* Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net>
|
||||
* Copyright (C) 2023 Stefan Bosch <stefan_b@posteo.net>
|
||||
*/
|
||||
|
||||
#include <asm-offsets.h>
|
||||
#include <asm/assembler.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
ENTRY(relocate_vectors)
|
||||
|
||||
/*
|
||||
* The s5p4418 SoC has the security extensions, so use VBAR to relocate
|
||||
* the exception vectors.
|
||||
*/
|
||||
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
|
||||
add r0, #0x400 /* vectors are after NSIH + 0x200 */
|
||||
mcr p15, 0, r0, c12, c0, 0 /* Set VBAR */
|
||||
ret lr
|
||||
|
||||
ENDPROC(relocate_vectors)
|
|
@ -2028,6 +2028,26 @@
|
|||
groups = "SPI2MOSI";
|
||||
};
|
||||
|
||||
pinctrl_thru0_default: thru0_default {
|
||||
function = "THRU0";
|
||||
groups = "THRU0";
|
||||
};
|
||||
|
||||
pinctrl_thru1_default: thru1_default {
|
||||
function = "THRU1";
|
||||
groups = "THRU1";
|
||||
};
|
||||
|
||||
pinctrl_thru2_default: thru2_default {
|
||||
function = "THRU2";
|
||||
groups = "THRU2";
|
||||
};
|
||||
|
||||
pinctrl_thru3_default: thru3_default {
|
||||
function = "THRU3";
|
||||
groups = "THRU3";
|
||||
};
|
||||
|
||||
pinctrl_timer3_default: timer3_default {
|
||||
function = "TIMER3";
|
||||
groups = "TIMER3";
|
||||
|
|
|
@ -87,10 +87,12 @@
|
|||
pins = "SPI2_CSB", "SPI2_MISO", "SPI2_MOSI",
|
||||
"SPI2_CLK", "SPI2_HOLD";
|
||||
input-enable;
|
||||
drive-strength = <MTK_DRIVE_4mA>;
|
||||
};
|
||||
|
||||
conf-clk {
|
||||
pins = "SPI2_WP";
|
||||
drive-strength = <MTK_DRIVE_4mA>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <dt-bindings/clock/mt7988-clk.h>
|
||||
#include <dt-bindings/reset/mt7988-reset.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pinctrl/mt65xx.h>
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
|
||||
/ {
|
||||
|
|
|
@ -127,6 +127,18 @@ int dram_init(void)
|
|||
if (fdtdec_setup_mem_size_base() != 0)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* When LPAE is enabled (ARMv7),
|
||||
* 1:1 mapping is created using 2 MB blocks.
|
||||
*
|
||||
* In case amount of memory provided to QEMU
|
||||
* is not multiple of 2 MB, round down the amount
|
||||
* of available memory to avoid hang during MMU
|
||||
* initialization.
|
||||
*/
|
||||
if (CONFIG_IS_ENABLED(ARMV7_LPAE))
|
||||
gd->ram_size -= (gd->ram_size % 0x200000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
DEVELOPER BOX
|
||||
M: Jassi Brar <jaswinder.singh@linaro.org>
|
||||
M: Masahisa Kojima <kojima.masahisa@socionext.com>
|
||||
S: Maintained
|
||||
F: arch/arm/dts/synquacer-*
|
||||
F: board/socionext/developerbox/*
|
||||
|
|
|
@ -35,3 +35,34 @@ void set_dfu_alt_info(char *interface, char *devstr)
|
|||
|
||||
env_set("dfu_alt_info", buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwu_plat_get_bootidx() - Get the value of the boot index
|
||||
* @boot_idx: Boot index value
|
||||
*
|
||||
* Get the value of the bank(partition) from which the platform
|
||||
* has booted. This value is passed to U-Boot from the earlier
|
||||
* stage bootloader which loads and boots all the relevant
|
||||
* firmware images
|
||||
*/
|
||||
void fwu_plat_get_bootidx(uint *boot_idx)
|
||||
{
|
||||
int ret;
|
||||
u32 buf;
|
||||
size_t readlen;
|
||||
struct mtd_info *mtd;
|
||||
|
||||
*boot_idx = 0;
|
||||
|
||||
mtd_probe_devices();
|
||||
mtd = get_mtd_device_nm("nor1");
|
||||
if (IS_ERR_OR_NULL(mtd))
|
||||
return;
|
||||
|
||||
ret = mtd_read(mtd, SCB_PLAT_METADATA_OFFSET, sizeof(buf),
|
||||
&readlen, (u_char *)&buf);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
*boot_idx = buf;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define GUEST_VIRTIO_MMIO_BASE 0x2000000
|
||||
#define GUEST_VIRTIO_MMIO_SIZE 0x100000
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
return 0;
|
||||
|
@ -212,6 +215,15 @@ static int setup_mem_map(void)
|
|||
PTE_BLOCK_INNER_SHARE);
|
||||
i++;
|
||||
|
||||
if (CONFIG_IS_ENABLED(VIRTIO_MMIO)) {
|
||||
xen_mem_map[i].virt = GUEST_VIRTIO_MMIO_BASE;
|
||||
xen_mem_map[i].phys = GUEST_VIRTIO_MMIO_BASE;
|
||||
xen_mem_map[i].size = GUEST_VIRTIO_MMIO_SIZE;
|
||||
xen_mem_map[i].attrs = (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
|
||||
PTE_BLOCK_NON_SHARE);
|
||||
i++;
|
||||
}
|
||||
|
||||
mem = get_next_memory_node(blob, -1);
|
||||
if (mem < 0) {
|
||||
printf("%s: Missing /memory node\n", __func__);
|
||||
|
@ -219,6 +231,11 @@ static int setup_mem_map(void)
|
|||
}
|
||||
|
||||
for (; i < MAX_MEM_MAP_REGIONS; i++) {
|
||||
if (CONFIG_IS_ENABLED(VIRTIO_MMIO)) {
|
||||
ret = fdt_node_check_compatible(blob, mem, "virtio,mmio");
|
||||
if (!ret)
|
||||
continue;
|
||||
}
|
||||
ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
|
||||
if (ret == -FDT_ERR_NOTFOUND) {
|
||||
reg = 0;
|
||||
|
|
|
@ -39,7 +39,6 @@ int bootdev_add_bootflow(struct bootflow *bflow)
|
|||
struct bootflow *new;
|
||||
int ret;
|
||||
|
||||
assert(bflow->dev);
|
||||
ret = bootstd_get_priv(&std);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -173,8 +172,10 @@ int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk,
|
|||
*/
|
||||
iter->max_part = MAX_PART_PER_BOOTDEV;
|
||||
|
||||
/* If this is the whole disk, check if we have bootable partitions */
|
||||
if (!iter->part) {
|
||||
if (iter->flags & BOOTFLOWIF_SINGLE_PARTITION) {
|
||||
/* a particular partition was specified, scan it without checking */
|
||||
} else if (!iter->part) {
|
||||
/* This is the whole disk, check if we have bootable partitions */
|
||||
iter->first_bootable = part_get_bootable(desc);
|
||||
log_debug("checking bootable=%d\n", iter->first_bootable);
|
||||
} else if (allow_any_part) {
|
||||
|
@ -711,8 +712,37 @@ int bootdev_setup_iter(struct bootflow_iter *iter, const char *label,
|
|||
struct udevice *bootstd, *dev = NULL;
|
||||
bool show = iter->flags & BOOTFLOWIF_SHOW;
|
||||
int method_flags;
|
||||
char buf[32];
|
||||
int ret;
|
||||
|
||||
if (label) {
|
||||
const char *end = strchr(label, ':');
|
||||
|
||||
if (end) {
|
||||
size_t len = (size_t)(end - label);
|
||||
const char *part = end + 1;
|
||||
|
||||
if (len + 1 > sizeof(buf)) {
|
||||
log_err("label \"%s\" is way too long\n", label);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(buf, label, len);
|
||||
buf[len] = '\0';
|
||||
label = buf;
|
||||
|
||||
unsigned long tmp;
|
||||
|
||||
if (strict_strtoul(part, 0, &tmp)) {
|
||||
log_err("Invalid partition number: %s\n", part);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
iter->flags |= BOOTFLOWIF_SINGLE_PARTITION;
|
||||
iter->part = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
ret = uclass_first_device_err(UCLASS_BOOTSTD, &bootstd);
|
||||
if (ret) {
|
||||
log_err("Missing bootstd device\n");
|
||||
|
|
|
@ -217,6 +217,9 @@ static int iter_incr(struct bootflow_iter *iter)
|
|||
}
|
||||
}
|
||||
|
||||
if (iter->flags & BOOTFLOWIF_SINGLE_PARTITION)
|
||||
return BF_NO_MORE_DEVICES;
|
||||
|
||||
/* No more bootmeths; start at the first one, and... */
|
||||
iter->cur_method = 0;
|
||||
iter->method = iter->method_order[iter->cur_method];
|
||||
|
|
|
@ -17,6 +17,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
#define IMAGE_MAX_HASHED_NODES 100
|
||||
|
||||
struct checksum_algo checksum_algos[] = {
|
||||
#if CONFIG_IS_ENABLED(SHA1)
|
||||
{
|
||||
.name = "sha1",
|
||||
.checksum_len = SHA1_SUM_LEN,
|
||||
|
@ -24,6 +25,8 @@ struct checksum_algo checksum_algos[] = {
|
|||
.der_prefix = sha1_der_prefix,
|
||||
.calculate = hash_calculate,
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_IS_ENABLED(SHA256)
|
||||
{
|
||||
.name = "sha256",
|
||||
.checksum_len = SHA256_SUM_LEN,
|
||||
|
@ -31,7 +34,8 @@ struct checksum_algo checksum_algos[] = {
|
|||
.der_prefix = sha256_der_prefix,
|
||||
.calculate = hash_calculate,
|
||||
},
|
||||
#ifdef CONFIG_SHA384
|
||||
#endif
|
||||
#if CONFIG_IS_ENABLED(SHA384)
|
||||
{
|
||||
.name = "sha384",
|
||||
.checksum_len = SHA384_SUM_LEN,
|
||||
|
@ -40,7 +44,7 @@ struct checksum_algo checksum_algos[] = {
|
|||
.calculate = hash_calculate,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_SHA512
|
||||
#if CONFIG_IS_ENABLED(SHA512)
|
||||
{
|
||||
.name = "sha512",
|
||||
.checksum_len = SHA512_SUM_LEN,
|
||||
|
|
|
@ -634,7 +634,12 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
|
|||
char *fdtfilefree = NULL;
|
||||
|
||||
if (label->fdt) {
|
||||
fdtfile = label->fdt;
|
||||
if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
|
||||
if (strcmp("-", label->fdt))
|
||||
fdtfile = label->fdt;
|
||||
} else {
|
||||
fdtfile = label->fdt;
|
||||
}
|
||||
} else if (label->fdtdir) {
|
||||
char *f1, *f2, *f3, *f4, *slash;
|
||||
|
||||
|
@ -731,14 +736,26 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
|
|||
zboot_argc = 5;
|
||||
}
|
||||
|
||||
if (!bootm_argv[3])
|
||||
bootm_argv[3] = env_get("fdt_addr");
|
||||
if (!bootm_argv[3]) {
|
||||
if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
|
||||
if (strcmp("-", label->fdt))
|
||||
bootm_argv[3] = env_get("fdt_addr");
|
||||
} else {
|
||||
bootm_argv[3] = env_get("fdt_addr");
|
||||
}
|
||||
}
|
||||
|
||||
kernel_addr_r = genimg_get_kernel_addr(kernel_addr);
|
||||
buf = map_sysmem(kernel_addr_r, 0);
|
||||
|
||||
if (!bootm_argv[3] && genimg_get_format(buf) != IMAGE_FORMAT_FIT)
|
||||
bootm_argv[3] = env_get("fdtcontroladdr");
|
||||
if (!bootm_argv[3] && genimg_get_format(buf) != IMAGE_FORMAT_FIT) {
|
||||
if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
|
||||
if (strcmp("-", label->fdt))
|
||||
bootm_argv[3] = env_get("fdtcontroladdr");
|
||||
} else {
|
||||
bootm_argv[3] = env_get("fdtcontroladdr");
|
||||
}
|
||||
}
|
||||
|
||||
if (bootm_argv[3]) {
|
||||
if (!bootm_argv[2])
|
||||
|
|
10
cmd/Kconfig
10
cmd/Kconfig
|
@ -740,6 +740,7 @@ config CRC32_VERIFY
|
|||
|
||||
config CMD_EEPROM
|
||||
bool "eeprom - EEPROM subsystem"
|
||||
depends on DM_I2C || SYS_I2C_LEGACY
|
||||
help
|
||||
(deprecated, needs conversion to driver model)
|
||||
Provides commands to read and write EEPROM (Electrically Erasable
|
||||
|
@ -2750,15 +2751,6 @@ config MTDPARTS_DEFAULT
|
|||
Defines a default MTD partitioning scheme in the Linux MTD command
|
||||
line partitions format
|
||||
|
||||
config CMD_REISER
|
||||
bool "reiser - Access to reiserfs filesystems"
|
||||
help
|
||||
This provides two commands which operate on a resierfs filesystem,
|
||||
commonly used some years ago:
|
||||
|
||||
reiserls - list files
|
||||
reiserload - load a file
|
||||
|
||||
config CMD_YAFFS2
|
||||
bool "yaffs2 - Access of YAFFS2 filesystem"
|
||||
depends on YAFFS2
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
|
||||
static int do_unaligned(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
|
|
171
cmd/reiser.c
171
cmd/reiser.c
|
@ -1,171 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2003 - 2004
|
||||
* Sysgo Real-Time Solutions, AG <www.elinos.com>
|
||||
* Pavel Bartusek <pba@sysgo.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Reiserfs support
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <config.h>
|
||||
#include <command.h>
|
||||
#include <env.h>
|
||||
#include <image.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <reiserfs.h>
|
||||
#include <part.h>
|
||||
|
||||
#if !CONFIG_IS_ENABLED(DOS_PARTITION)
|
||||
#error DOS partition support must be selected
|
||||
#endif
|
||||
|
||||
/* #define REISER_DEBUG */
|
||||
|
||||
#ifdef REISER_DEBUG
|
||||
#define PRINTF(fmt,args...) printf (fmt ,##args)
|
||||
#else
|
||||
#define PRINTF(fmt,args...)
|
||||
#endif
|
||||
|
||||
int do_reiserls(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
char *filename = "/";
|
||||
int dev, part;
|
||||
struct blk_desc *dev_desc = NULL;
|
||||
struct disk_partition info;
|
||||
|
||||
if (argc < 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
part = blk_get_device_part_str(argv[1], argv[2], &dev_desc, &info, 1);
|
||||
if (part < 0)
|
||||
return 1;
|
||||
|
||||
if (argc == 4) {
|
||||
filename = argv[3];
|
||||
}
|
||||
|
||||
dev = dev_desc->devnum;
|
||||
PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename);
|
||||
|
||||
reiserfs_set_blk_dev(dev_desc, &info);
|
||||
|
||||
if (!reiserfs_mount(info.size)) {
|
||||
printf ("** Bad Reiserfs partition or disk - %s %d:%d **\n", argv[1], dev, part);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (reiserfs_ls (filename)) {
|
||||
printf ("** Error reiserfs_ls() **\n");
|
||||
return 1;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
reiserls, 4, 1, do_reiserls,
|
||||
"list files in a directory (default /)",
|
||||
"<interface> <dev[:part]> [directory]\n"
|
||||
" - list files from 'dev' on 'interface' in a 'directory'"
|
||||
);
|
||||
|
||||
/******************************************************************************
|
||||
* Reiserfs boot command intepreter. Derived from diskboot
|
||||
*/
|
||||
int do_reiserload(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
char *filename = NULL;
|
||||
int dev, part;
|
||||
ulong addr = 0, filelen;
|
||||
struct disk_partition info;
|
||||
struct blk_desc *dev_desc = NULL;
|
||||
unsigned long count;
|
||||
char *addr_str;
|
||||
|
||||
switch (argc) {
|
||||
case 3:
|
||||
addr_str = env_get("loadaddr");
|
||||
if (addr_str != NULL) {
|
||||
addr = hextoul(addr_str, NULL);
|
||||
} else {
|
||||
addr = CONFIG_SYS_LOAD_ADDR;
|
||||
}
|
||||
filename = env_get("bootfile");
|
||||
count = 0;
|
||||
break;
|
||||
case 4:
|
||||
addr = hextoul(argv[3], NULL);
|
||||
filename = env_get("bootfile");
|
||||
count = 0;
|
||||
break;
|
||||
case 5:
|
||||
addr = hextoul(argv[3], NULL);
|
||||
filename = argv[4];
|
||||
count = 0;
|
||||
break;
|
||||
case 6:
|
||||
addr = hextoul(argv[3], NULL);
|
||||
filename = argv[4];
|
||||
count = hextoul(argv[5], NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
puts ("\n** No boot file defined **\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
part = blk_get_device_part_str(argv[1], argv[2], &dev_desc, &info, 1);
|
||||
if (part < 0)
|
||||
return 1;
|
||||
|
||||
dev = dev_desc->devnum;
|
||||
|
||||
printf("Loading file \"%s\" from %s device %d%c%c\n",
|
||||
filename, argv[1], dev,
|
||||
part ? ':' : ' ', part ? part + '0' : ' ');
|
||||
|
||||
reiserfs_set_blk_dev(dev_desc, &info);
|
||||
|
||||
if (!reiserfs_mount(info.size)) {
|
||||
printf ("** Bad Reiserfs partition or disk - %s %d:%d **\n", argv[1], dev, part);
|
||||
return 1;
|
||||
}
|
||||
|
||||
filelen = reiserfs_open(filename);
|
||||
if (filelen < 0) {
|
||||
printf("** File not found %s **\n", filename);
|
||||
return 1;
|
||||
}
|
||||
if ((count < filelen) && (count != 0)) {
|
||||
filelen = count;
|
||||
}
|
||||
|
||||
if (reiserfs_read((char *)addr, filelen) != filelen) {
|
||||
printf("\n** Unable to read \"%s\" from %s %d:%d **\n", filename, argv[1], dev, part);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Loading ok, update default load address */
|
||||
image_load_addr = addr;
|
||||
|
||||
printf ("\n%ld bytes read\n", filelen);
|
||||
env_set_hex("filesize", filelen);
|
||||
|
||||
return filelen;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
reiserload, 6, 0, do_reiserload,
|
||||
"load binary file from a Reiser filesystem",
|
||||
"<interface> <dev[:part]> [addr] [filename] [bytes]\n"
|
||||
" - load binary file 'filename' from 'dev' on 'interface'\n"
|
||||
" to address 'addr' from dos filesystem"
|
||||
);
|
|
@ -5,7 +5,6 @@
|
|||
* Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
|
||||
static int do_compressed(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
|
||||
static int do_sigsegv(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
|
|
|
@ -216,14 +216,12 @@ int setexpr_regex_sub(char *data, uint data_size, char *nbuf, uint nbuf_size,
|
|||
if (res == 0) {
|
||||
if (loop == 0) {
|
||||
debug("%s: No match\n", data);
|
||||
return 1;
|
||||
} else {
|
||||
break;
|
||||
debug("## MATCH ## %s\n", data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
debug("## MATCH ## %s\n", data);
|
||||
|
||||
if (!s)
|
||||
return 1;
|
||||
|
||||
|
@ -540,7 +538,8 @@ U_BOOT_CMD(
|
|||
" - For each substring matching the regular expression <r> in the\n"
|
||||
" string <t>, substitute the string <s>. The result is\n"
|
||||
" assigned to <name>. If <t> is not supplied, use the old\n"
|
||||
" value of <name>\n"
|
||||
" value of <name>. If no substring matching <r> is found in <t>,\n"
|
||||
" assign <t> to <name>.\n"
|
||||
"setexpr name sub r s [t]\n"
|
||||
" - Just like gsub(), but replace only the first matching substring"
|
||||
#endif
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
|
||||
static int do_undefined(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
|
|
|
@ -282,7 +282,9 @@ static int init_func_i2c(void)
|
|||
|
||||
static int setup_mon_len(void)
|
||||
{
|
||||
#if defined(__ARM__) || defined(__MICROBLAZE__)
|
||||
#if defined(CONFIG_ARCH_NEXELL)
|
||||
gd->mon_len = (ulong)__bss_end - (ulong)__image_copy_start;
|
||||
#elif defined(__ARM__) || defined(__MICROBLAZE__)
|
||||
gd->mon_len = (ulong)__bss_end - (ulong)_start;
|
||||
#elif defined(CONFIG_SANDBOX) && !defined(__riscv)
|
||||
gd->mon_len = (ulong)_end - (ulong)_init;
|
||||
|
|
|
@ -428,6 +428,11 @@ int log_device_set_enable(struct log_driver *drv, bool enable)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void log_fixup_for_gd_move(struct global_data *new_gd)
|
||||
{
|
||||
new_gd->log_head.prev->next = &new_gd->log_head;
|
||||
}
|
||||
|
||||
int log_init(void)
|
||||
{
|
||||
struct log_driver *drv = ll_entry_start(struct log_driver, log_driver);
|
||||
|
|
|
@ -909,6 +909,9 @@ ulong spl_relocate_stack_gd(void)
|
|||
#if CONFIG_IS_ENABLED(DM)
|
||||
dm_fixup_for_gd_move(new_gd);
|
||||
#endif
|
||||
#if CONFIG_IS_ENABLED(LOG)
|
||||
log_fixup_for_gd_move(new_gd);
|
||||
#endif
|
||||
#if !defined(CONFIG_ARM) && !defined(CONFIG_RISCV)
|
||||
gd = new_gd;
|
||||
#endif
|
||||
|
|
|
@ -53,7 +53,6 @@ CONFIG_CMD_JFFS2=y
|
|||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_MTDIDS_DEFAULT="nand0=atmel_nand"
|
||||
CONFIG_MTDPARTS_DEFAULT="mtdparts=atmel_nand:-(root)"
|
||||
CONFIG_CMD_REISER=y
|
||||
CONFIG_CMD_UBI=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_ENV_IS_IN_SPI_FLASH=y
|
||||
|
|
|
@ -531,6 +531,10 @@ Then the iterator is set up to according to the parameters given:
|
|||
`BOOTFLOWIF_SINGLE_MEDIA` is set. In this case, moving to the next bootdev
|
||||
processes just the children of the media device. Hunters are used, in this
|
||||
example just the "mmc" hunter.
|
||||
- If `label` indicates a particular partition in a particular media device
|
||||
(e.g. "mmc1:3") then `BOOTFLOWIF_SINGLE_PARTITION` is set. In this case,
|
||||
only a single partition within a bootdev is processed. Hunters are used, in
|
||||
this example just the "mmc" hunter.
|
||||
- If `label` indicates a media uclass (e.g. "mmc") then
|
||||
`BOOTFLOWIF_SINGLE_UCLASS` is set. In this case, all bootdevs in that uclass
|
||||
are used. Hunters are used, in this example just the "mmc" hunter
|
||||
|
|
|
@ -81,6 +81,12 @@ as specified at `Boot Loader Specification`_:
|
|||
* Does not document the fdtdir option, which automatically selects the DTB to
|
||||
pass to the kernel.
|
||||
|
||||
* If no fdt/fdtdir is provided, the U-Boot will pass its own currently used
|
||||
device tree.
|
||||
|
||||
* If ``-`` is passed as fdt argument and ``CONFIG_SUPPORT_PASSING_ATAGS`` is
|
||||
enabled, then no device tree will be used (legacy booting / pre-dtb kernel).
|
||||
|
||||
See also doc/README.pxe under 'pxe file format'.
|
||||
|
||||
One example extlinux.conf generated by the Fedora installer is::
|
||||
|
|
|
@ -39,6 +39,7 @@ setexpr name gsub <r> <s> [<t>]
|
|||
string <t>, substitute the string <s>.
|
||||
The result is assigned to <name>.
|
||||
If <t> is not supplied, use the old value of <name>.
|
||||
If no substring matching <r> is found in <t>, assign <t> to <name>.
|
||||
|
||||
setexpr name sub <r> <s> [<t>]
|
||||
Just like gsub(), but replace only the first matching substring
|
||||
|
|
|
@ -23,7 +23,7 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index)
|
|||
{
|
||||
#if CONFIG_IS_ENABLED(OF_REAL)
|
||||
int offset = dev_of_offset(dev);
|
||||
int parent = dev_of_offset(dev->parent);
|
||||
int parent = fdt_parent_offset(gd->fdt_blob, offset);
|
||||
fdt_addr_t addr;
|
||||
|
||||
if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {
|
||||
|
|
|
@ -128,6 +128,8 @@ struct macb_device {
|
|||
unsigned long dummy_desc_dma;
|
||||
|
||||
const struct device *dev;
|
||||
unsigned int duplex;
|
||||
unsigned int speed;
|
||||
unsigned short phy_addr;
|
||||
struct mii_dev *bus;
|
||||
#ifdef CONFIG_PHYLIB
|
||||
|
@ -178,6 +180,12 @@ static int gem_is_gigabit_capable(struct macb_device *macb)
|
|||
return macb_is_gem(macb) && !cpu_is_sama5d2() && !cpu_is_sama5d4();
|
||||
}
|
||||
|
||||
/* Is the port a fixed link */
|
||||
static int macb_port_is_fixed_link(struct macb_device *macb)
|
||||
{
|
||||
return macb->phy_addr > PHY_MAX_ADDR;
|
||||
}
|
||||
|
||||
static void macb_mdio_write(struct macb_device *macb, u8 phy_adr, u8 reg,
|
||||
u16 value)
|
||||
{
|
||||
|
@ -666,97 +674,109 @@ static int macb_phy_init(struct udevice *dev, const char *name)
|
|||
int i;
|
||||
|
||||
arch_get_mdio_control(name);
|
||||
/* Auto-detect phy_addr */
|
||||
ret = macb_phy_find(macb, name);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* If port is not fixed -> setup PHY */
|
||||
if (!macb_port_is_fixed_link(macb)) {
|
||||
/* Auto-detect phy_addr */
|
||||
ret = macb_phy_find(macb, name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Check if the PHY is up to snuff... */
|
||||
phy_id = macb_mdio_read(macb, macb->phy_addr, MII_PHYSID1);
|
||||
if (phy_id == 0xffff) {
|
||||
printf("%s: No PHY present\n", name);
|
||||
return -ENODEV;
|
||||
}
|
||||
/* Check if the PHY is up to snuff... */
|
||||
phy_id = macb_mdio_read(macb, macb->phy_addr, MII_PHYSID1);
|
||||
if (phy_id == 0xffff) {
|
||||
printf("%s: No PHY present\n", name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PHYLIB
|
||||
macb->phydev = phy_connect(macb->bus, macb->phy_addr, dev,
|
||||
macb->phy_interface);
|
||||
if (!macb->phydev) {
|
||||
printf("phy_connect failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
macb->phydev = phy_connect(macb->bus, macb->phy_addr, dev,
|
||||
macb->phy_interface);
|
||||
if (!macb->phydev) {
|
||||
printf("phy_connect failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
phy_config(macb->phydev);
|
||||
phy_config(macb->phydev);
|
||||
#endif
|
||||
|
||||
status = macb_mdio_read(macb, macb->phy_addr, MII_BMSR);
|
||||
if (!(status & BMSR_LSTATUS)) {
|
||||
/* Try to re-negotiate if we don't have link already. */
|
||||
macb_phy_reset(macb, name);
|
||||
status = macb_mdio_read(macb, macb->phy_addr, MII_BMSR);
|
||||
if (!(status & BMSR_LSTATUS)) {
|
||||
/* Try to re-negotiate if we don't have link already. */
|
||||
macb_phy_reset(macb, name);
|
||||
|
||||
for (i = 0; i < MACB_AUTONEG_TIMEOUT / 100; i++) {
|
||||
status = macb_mdio_read(macb, macb->phy_addr, MII_BMSR);
|
||||
if (status & BMSR_LSTATUS) {
|
||||
/*
|
||||
* Delay a bit after the link is established,
|
||||
* so that the next xfer does not fail
|
||||
*/
|
||||
mdelay(10);
|
||||
break;
|
||||
for (i = 0; i < MACB_AUTONEG_TIMEOUT / 100; i++) {
|
||||
status = macb_mdio_read(macb, macb->phy_addr, MII_BMSR);
|
||||
if (status & BMSR_LSTATUS) {
|
||||
/*
|
||||
* Delay a bit after the link is established,
|
||||
* so that the next xfer does not fail
|
||||
*/
|
||||
mdelay(10);
|
||||
break;
|
||||
}
|
||||
udelay(100);
|
||||
}
|
||||
udelay(100);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(status & BMSR_LSTATUS)) {
|
||||
printf("%s: link down (status: 0x%04x)\n",
|
||||
name, status);
|
||||
return -ENETDOWN;
|
||||
}
|
||||
|
||||
/* First check for GMAC and that it is GiB capable */
|
||||
if (gem_is_gigabit_capable(macb)) {
|
||||
lpa = macb_mdio_read(macb, macb->phy_addr, MII_STAT1000);
|
||||
|
||||
if (lpa & (LPA_1000FULL | LPA_1000HALF | LPA_1000XFULL |
|
||||
LPA_1000XHALF)) {
|
||||
duplex = ((lpa & (LPA_1000FULL | LPA_1000XFULL)) ?
|
||||
1 : 0);
|
||||
|
||||
printf("%s: link up, 1000Mbps %s-duplex (lpa: 0x%04x)\n",
|
||||
name,
|
||||
duplex ? "full" : "half",
|
||||
lpa);
|
||||
|
||||
ncfgr = macb_readl(macb, NCFGR);
|
||||
ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
|
||||
ncfgr |= GEM_BIT(GBE);
|
||||
|
||||
if (duplex)
|
||||
ncfgr |= MACB_BIT(FD);
|
||||
|
||||
macb_writel(macb, NCFGR, ncfgr);
|
||||
|
||||
ret = macb_linkspd_cb(dev, _1000BASET);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
if (!(status & BMSR_LSTATUS)) {
|
||||
printf("%s: link down (status: 0x%04x)\n",
|
||||
name, status);
|
||||
return -ENETDOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/* fall back for EMAC checking */
|
||||
adv = macb_mdio_read(macb, macb->phy_addr, MII_ADVERTISE);
|
||||
lpa = macb_mdio_read(macb, macb->phy_addr, MII_LPA);
|
||||
media = mii_nway_result(lpa & adv);
|
||||
speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
|
||||
? 1 : 0);
|
||||
duplex = (media & ADVERTISE_FULL) ? 1 : 0;
|
||||
printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
|
||||
name,
|
||||
speed ? "100" : "10",
|
||||
duplex ? "full" : "half",
|
||||
lpa);
|
||||
/* First check for GMAC and that it is GiB capable */
|
||||
if (gem_is_gigabit_capable(macb)) {
|
||||
lpa = macb_mdio_read(macb, macb->phy_addr, MII_STAT1000);
|
||||
|
||||
if (lpa & (LPA_1000FULL | LPA_1000HALF | LPA_1000XFULL |
|
||||
LPA_1000XHALF)) {
|
||||
duplex = ((lpa & (LPA_1000FULL | LPA_1000XFULL)) ?
|
||||
1 : 0);
|
||||
|
||||
printf("%s: link up, 1000Mbps %s-duplex (lpa: 0x%04x)\n",
|
||||
name,
|
||||
duplex ? "full" : "half",
|
||||
lpa);
|
||||
|
||||
ncfgr = macb_readl(macb, NCFGR);
|
||||
ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
|
||||
ncfgr |= GEM_BIT(GBE);
|
||||
|
||||
if (duplex)
|
||||
ncfgr |= MACB_BIT(FD);
|
||||
|
||||
macb_writel(macb, NCFGR, ncfgr);
|
||||
|
||||
ret = macb_linkspd_cb(dev, _1000BASET);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* fall back for EMAC checking */
|
||||
adv = macb_mdio_read(macb, macb->phy_addr, MII_ADVERTISE);
|
||||
lpa = macb_mdio_read(macb, macb->phy_addr, MII_LPA);
|
||||
media = mii_nway_result(lpa & adv);
|
||||
speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
|
||||
? 1 : 0);
|
||||
duplex = (media & ADVERTISE_FULL) ? 1 : 0;
|
||||
printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
|
||||
name,
|
||||
speed ? "100" : "10",
|
||||
duplex ? "full" : "half",
|
||||
lpa);
|
||||
} else {
|
||||
/* if macb port is a fixed link */
|
||||
/* TODO : manage gigabit capable processors */
|
||||
speed = macb->speed;
|
||||
duplex = macb->duplex;
|
||||
printf("%s: link up, %sMbps %s-duplex\n",
|
||||
name,
|
||||
speed ? "100" : "10",
|
||||
duplex ? "full" : "half");
|
||||
}
|
||||
|
||||
ncfgr = macb_readl(macb, NCFGR);
|
||||
ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD) | GEM_BIT(GBE));
|
||||
|
@ -1276,6 +1296,28 @@ int __weak macb_late_eth_of_to_plat(struct udevice *dev)
|
|||
static int macb_eth_of_to_plat(struct udevice *dev)
|
||||
{
|
||||
struct eth_pdata *pdata = dev_get_plat(dev);
|
||||
struct macb_device *macb = dev_get_priv(dev);
|
||||
void *blob = (void *)gd->fdt_blob;
|
||||
int node = dev_of_offset(dev);
|
||||
int fl_node, speed_fdt;
|
||||
|
||||
/* fetch 'fixed-link' property */
|
||||
fl_node = fdt_subnode_offset(blob, node, "fixed-link");
|
||||
if (fl_node >= 0) {
|
||||
/* set phy_addr to invalid value for fixed link */
|
||||
macb->phy_addr = PHY_MAX_ADDR + 1;
|
||||
macb->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
|
||||
speed_fdt = fdtdec_get_int(blob, fl_node, "speed", 0);
|
||||
if (speed_fdt == 100) {
|
||||
macb->speed = 1;
|
||||
} else if (speed_fdt == 10) {
|
||||
macb->speed = 0;
|
||||
} else {
|
||||
printf("%s: The given speed %d of ethernet in the DT is not supported\n",
|
||||
__func__, speed_fdt);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
pdata->iobase = (uintptr_t)dev_remap_addr(dev);
|
||||
if (!pdata->iobase)
|
||||
|
|
|
@ -137,6 +137,7 @@ struct mtk_eth_priv {
|
|||
int force_mode;
|
||||
int speed;
|
||||
int duplex;
|
||||
int mdc;
|
||||
bool pn_swap;
|
||||
|
||||
struct phy_device *phydev;
|
||||
|
@ -1245,7 +1246,8 @@ static int mtk_phy_start(struct mtk_eth_priv *priv)
|
|||
}
|
||||
|
||||
if (!priv->force_mode) {
|
||||
if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII)
|
||||
if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
|
||||
priv->phy_interface == PHY_INTERFACE_MODE_XGMII)
|
||||
mtk_xphy_link_adjust(priv);
|
||||
else
|
||||
mtk_phy_link_adjust(priv);
|
||||
|
@ -1515,7 +1517,7 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
|
|||
|
||||
static void mtk_xmac_init(struct mtk_eth_priv *priv)
|
||||
{
|
||||
u32 sts;
|
||||
u32 force_link = 0;
|
||||
|
||||
switch (priv->phy_interface) {
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
|
@ -1530,15 +1532,19 @@ static void mtk_xmac_init(struct mtk_eth_priv *priv)
|
|||
SYSCFG0_GE_MODE_M << SYSCFG0_GE_MODE_S(priv->gmac_id),
|
||||
0);
|
||||
|
||||
if (priv->gmac_id == 1) {
|
||||
if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII &&
|
||||
priv->gmac_id == 1) {
|
||||
mtk_infra_rmw(priv, TOPMISC_NETSYS_PCS_MUX,
|
||||
NETSYS_PCS_MUX_MASK, MUX_G2_USXGMII_SEL);
|
||||
} else if (priv->gmac_id == 2) {
|
||||
sts = mtk_gmac_read(priv, XGMAC_STS(priv->gmac_id));
|
||||
sts |= XGMAC_FORCE_LINK;
|
||||
mtk_gmac_write(priv, XGMAC_STS(priv->gmac_id), sts);
|
||||
}
|
||||
|
||||
if (priv->phy_interface == PHY_INTERFACE_MODE_XGMII ||
|
||||
priv->gmac_id == 2)
|
||||
force_link = XGMAC_FORCE_LINK(priv->gmac_id);
|
||||
|
||||
mtk_gmac_rmw(priv, XGMAC_STS(priv->gmac_id),
|
||||
XGMAC_FORCE_LINK(priv->gmac_id), force_link);
|
||||
|
||||
/* Force GMAC link down */
|
||||
mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), FORCE_MODE);
|
||||
}
|
||||
|
@ -1607,6 +1613,26 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
|
|||
mtk_pdma_write(priv, PDMA_RST_IDX_REG, RST_DTX_IDX0 | RST_DRX_IDX0);
|
||||
}
|
||||
|
||||
static void mtk_eth_mdc_init(struct mtk_eth_priv *priv)
|
||||
{
|
||||
u32 divider;
|
||||
|
||||
if (priv->mdc == 0)
|
||||
return;
|
||||
|
||||
divider = min_t(u32, DIV_ROUND_UP(MDC_MAX_FREQ, priv->mdc), MDC_MAX_DIVIDER);
|
||||
|
||||
/* Configure MDC turbo mode */
|
||||
if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V3))
|
||||
mtk_gmac_rmw(priv, GMAC_MAC_MISC_REG, 0, MISC_MDC_TURBO);
|
||||
else
|
||||
mtk_gmac_rmw(priv, GMAC_PPSC_REG, 0, MISC_MDC_TURBO);
|
||||
|
||||
/* Configure MDC divider */
|
||||
mtk_gmac_rmw(priv, GMAC_PPSC_REG, PHY_MDC_CFG,
|
||||
FIELD_PREP(PHY_MDC_CFG, divider));
|
||||
}
|
||||
|
||||
static int mtk_eth_start(struct udevice *dev)
|
||||
{
|
||||
struct mtk_eth_priv *priv = dev_get_priv(dev);
|
||||
|
@ -1803,8 +1829,12 @@ static int mtk_eth_probe(struct udevice *dev)
|
|||
noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC,
|
||||
ARCH_DMA_MINALIGN);
|
||||
|
||||
/* Set MDC divider */
|
||||
mtk_eth_mdc_init(priv);
|
||||
|
||||
/* Set MAC mode */
|
||||
if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII)
|
||||
if (priv->phy_interface == PHY_INTERFACE_MODE_USXGMII ||
|
||||
priv->phy_interface == PHY_INTERFACE_MODE_XGMII)
|
||||
mtk_xmac_init(priv);
|
||||
else
|
||||
mtk_mac_init(priv);
|
||||
|
@ -1881,6 +1911,17 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
|
|||
|
||||
priv->gmac_id = dev_read_u32_default(dev, "mediatek,gmac-id", 0);
|
||||
|
||||
priv->mdc = 0;
|
||||
subnode = ofnode_find_subnode(dev_ofnode(dev), "mdio");
|
||||
if (ofnode_valid(subnode)) {
|
||||
priv->mdc = ofnode_read_u32_default(subnode, "clock-frequency", 2500000);
|
||||
if (priv->mdc > MDC_MAX_FREQ ||
|
||||
priv->mdc < MDC_MAX_FREQ / MDC_MAX_DIVIDER) {
|
||||
printf("error: MDIO clock frequency out of range\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Interface mode is required */
|
||||
pdata->phy_interface = dev_read_phy_mode(dev);
|
||||
priv->phy_interface = pdata->phy_interface;
|
||||
|
|
|
@ -180,6 +180,12 @@ enum mkt_eth_capabilities {
|
|||
|
||||
/* GMAC Registers */
|
||||
|
||||
#define GMAC_PPSC_REG 0x0000
|
||||
#define PHY_MDC_CFG GENMASK(29, 24)
|
||||
#define MDC_TURBO BIT(20)
|
||||
#define MDC_MAX_FREQ 25000000
|
||||
#define MDC_MAX_DIVIDER 63
|
||||
|
||||
#define GMAC_PIAC_REG 0x0004
|
||||
#define PHY_ACS_ST BIT(31)
|
||||
#define MDIO_REG_ADDR_S 25
|
||||
|
@ -197,6 +203,7 @@ enum mkt_eth_capabilities {
|
|||
#define P1_XGMAC_FORCE_LINK BIT(15)
|
||||
|
||||
#define GMAC_MAC_MISC_REG 0x0010
|
||||
#define MISC_MDC_TURBO BIT(4)
|
||||
|
||||
#define GMAC_GSW_CFG_REG 0x0080
|
||||
#define GSWTX_IPG_M 0xF0000
|
||||
|
@ -261,7 +268,7 @@ enum mkt_eth_capabilities {
|
|||
|
||||
/* XGMAC Status Registers */
|
||||
#define XGMAC_STS(x) (((x) == 2) ? 0x001C : 0x000C)
|
||||
#define XGMAC_FORCE_LINK BIT(15)
|
||||
#define XGMAC_FORCE_LINK(x) (((x) == 1) ? BIT(31) : BIT(15))
|
||||
|
||||
/* XGMAC Registers */
|
||||
#define XGMAC_PORT_MCR(x) (0x2000 + (((x) - 1) * 0x1000))
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <pci.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/printk.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
@ -133,18 +133,17 @@ static int pci_generic_ecam_write_config(struct udevice *bus, pci_dev_t bdf,
|
|||
static int pci_generic_ecam_of_to_plat(struct udevice *dev)
|
||||
{
|
||||
struct generic_ecam_pcie *pcie = dev_get_priv(dev);
|
||||
struct fdt_resource reg_res;
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
ofnode node = dev_ofnode(dev);
|
||||
struct resource reg_res;
|
||||
int err;
|
||||
|
||||
err = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev), "reg",
|
||||
0, ®_res);
|
||||
err = ofnode_read_resource(node, 0, ®_res);
|
||||
if (err < 0) {
|
||||
pr_err("\"reg\" resource not found\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
pcie->size = fdt_resource_size(®_res);
|
||||
pcie->size = resource_size(®_res);
|
||||
pcie->cfg_base = map_physmem(reg_res.start, pcie->size, MAP_NOCACHE);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -267,6 +267,14 @@ static struct aspeed_sig_desc fmcquad_link[] = {
|
|||
{ 0x438, GENMASK(5, 4), 0 },
|
||||
};
|
||||
|
||||
static struct aspeed_sig_desc siopbi_link[] = {
|
||||
{ 0x418, BIT(6), 0 },
|
||||
};
|
||||
|
||||
static struct aspeed_sig_desc siopbo_link[] = {
|
||||
{ 0x418, BIT(5), 0 },
|
||||
};
|
||||
|
||||
static struct aspeed_sig_desc spi1_link[] = {
|
||||
{ 0x438, GENMASK(13, 11), 0 },
|
||||
};
|
||||
|
@ -303,6 +311,22 @@ static struct aspeed_sig_desc spi2quad_link[] = {
|
|||
{ 0x434, GENMASK(31, 30), 0 },
|
||||
};
|
||||
|
||||
static struct aspeed_sig_desc thru0_link[] = {
|
||||
{ 0x4bc, GENMASK(25, 24), 0 },
|
||||
};
|
||||
|
||||
static struct aspeed_sig_desc thru1_link[] = {
|
||||
{ 0x4bc, GENMASK(27, 26), 0 },
|
||||
};
|
||||
|
||||
static struct aspeed_sig_desc thru2_link[] = {
|
||||
{ 0x4bc, GENMASK(29, 28), 0 },
|
||||
};
|
||||
|
||||
static struct aspeed_sig_desc thru3_link[] = {
|
||||
{ 0x4bc, GENMASK(31, 30), 0 },
|
||||
};
|
||||
|
||||
static struct aspeed_sig_desc fsi1[] = {
|
||||
{ 0xd48, GENMASK(21, 20), 0 },
|
||||
};
|
||||
|
@ -458,6 +482,8 @@ static const struct aspeed_group_config ast2600_groups[] = {
|
|||
{ "EMMC", ARRAY_SIZE(emmc_link), emmc_link },
|
||||
{ "EMMCG8", ARRAY_SIZE(emmcg8_link), emmcg8_link },
|
||||
{ "FMCQUAD", ARRAY_SIZE(fmcquad_link), fmcquad_link },
|
||||
{ "SIOPBI", ARRAY_SIZE(siopbi_link), siopbi_link },
|
||||
{ "SIOPBO", ARRAY_SIZE(siopbo_link), siopbo_link },
|
||||
{ "SPI1", ARRAY_SIZE(spi1_link), spi1_link },
|
||||
{ "SPI1ABR", ARRAY_SIZE(spi1abr_link), spi1abr_link },
|
||||
{ "SPI1CS1", ARRAY_SIZE(spi1cs1_link), spi1cs1_link },
|
||||
|
@ -467,6 +493,10 @@ static const struct aspeed_group_config ast2600_groups[] = {
|
|||
{ "SPI2CS1", ARRAY_SIZE(spi2cs1_link), spi2cs1_link },
|
||||
{ "SPI2CS2", ARRAY_SIZE(spi2cs2_link), spi2cs2_link },
|
||||
{ "SPI2QUAD", ARRAY_SIZE(spi2quad_link), spi2quad_link },
|
||||
{ "THRU0", ARRAY_SIZE(thru0_link), thru0_link },
|
||||
{ "THRU1", ARRAY_SIZE(thru1_link), thru1_link },
|
||||
{ "THRU2", ARRAY_SIZE(thru2_link), thru2_link },
|
||||
{ "THRU3", ARRAY_SIZE(thru3_link), thru3_link },
|
||||
{ "I2C1", ARRAY_SIZE(i2c1_link), i2c1_link },
|
||||
{ "I2C2", ARRAY_SIZE(i2c2_link), i2c2_link },
|
||||
{ "I2C3", ARRAY_SIZE(i2c3_link), i2c3_link },
|
||||
|
|
|
@ -100,6 +100,22 @@ static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool ofnode_pre_reloc_recursive(ofnode parent)
|
||||
{
|
||||
ofnode child;
|
||||
|
||||
if (ofnode_pre_reloc(parent))
|
||||
return true;
|
||||
|
||||
if (CONFIG_IS_ENABLED(PINCONF_RECURSIVE)) {
|
||||
ofnode_for_each_subnode(child, parent)
|
||||
if (ofnode_pre_reloc_recursive(child))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinconfig_post_bind() - post binding for PINCONFIG uclass
|
||||
* Recursively bind its children as pinconfig devices.
|
||||
|
@ -119,7 +135,7 @@ static int pinconfig_post_bind(struct udevice *dev)
|
|||
|
||||
dev_for_each_subnode(node, dev) {
|
||||
if (pre_reloc_only &&
|
||||
!ofnode_pre_reloc(node))
|
||||
!ofnode_pre_reloc_recursive(node))
|
||||
continue;
|
||||
/*
|
||||
* If this node has "compatible" property, this is not
|
||||
|
|
|
@ -9,11 +9,10 @@
|
|||
|
||||
#define LOG_CATEGORY UCLASS_RNG
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <rng.h>
|
||||
#include <asm/system.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#define DRIVER_NAME "arm-rndr"
|
||||
|
||||
|
|
|
@ -5,11 +5,10 @@
|
|||
* Driver for Raspberry Pi hardware random number generator
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <rng.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#define usleep_range(a, b) udelay((b))
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* Driver for Amlogic hardware random number generator
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <rng.h>
|
||||
|
|
|
@ -9,12 +9,11 @@
|
|||
* Based on Linux driver
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <rng.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
/* Device specific register offsets */
|
||||
#define PRNG_DATA_OUT 0x0000
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* Copyright (c) 2022 Nuvoton Technology Corp.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <malloc.h>
|
||||
#include <rng.h>
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
*/
|
||||
#define LOG_CATEGORY UCLASS_RNG
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <rng.h>
|
||||
#include <tee.h>
|
||||
#include <dm/device.h>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#define LOG_CATEGORY UCLASS_RNG
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <rng.h>
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <rng.h>
|
||||
#include <asm/arch-rockchip/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/string.h>
|
||||
#include <rng.h>
|
||||
|
||||
#define RK_HW_RNG_MAX 32
|
||||
|
||||
|
|
|
@ -3,11 +3,10 @@
|
|||
* Copyright (c) 2019, Linaro Limited
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <rand.h>
|
||||
#include <rng.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
static int sandbox_rng_read(struct udevice *dev, void *data, size_t len)
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#define LOG_CATEGORY UCLASS_RNG
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <linker_lists.h>
|
||||
#include <log.h>
|
||||
|
|
|
@ -5,16 +5,14 @@
|
|||
|
||||
#define LOG_CATEGORY UCLASS_RNG
|
||||
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <log.h>
|
||||
#include <reset.h>
|
||||
#include <rng.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@ source "fs/cbfs/Kconfig"
|
|||
|
||||
source "fs/ext4/Kconfig"
|
||||
|
||||
source "fs/reiserfs/Kconfig"
|
||||
|
||||
source "fs/fat/Kconfig"
|
||||
|
||||
source "fs/jffs2/Kconfig"
|
||||
|
|
|
@ -19,7 +19,6 @@ obj-$(CONFIG_CMD_CRAMFS) += cramfs/
|
|||
obj-$(CONFIG_FS_EXT4) += ext4/
|
||||
obj-$(CONFIG_FS_FAT) += fat/
|
||||
obj-$(CONFIG_FS_JFFS2) += jffs2/
|
||||
obj-$(CONFIG_CMD_REISER) += reiserfs/
|
||||
obj-$(CONFIG_SANDBOX) += sandbox/
|
||||
obj-$(CONFIG_SEMIHOSTING) += semihostingfs.o
|
||||
obj-$(CONFIG_CMD_UBIFS) += ubifs/
|
||||
|
|
|
@ -2214,9 +2214,8 @@ static char *ext4fs_read_symlink(struct ext2fs_node *node)
|
|||
return symlink;
|
||||
}
|
||||
|
||||
static int ext4fs_find_file1(const char *currpath,
|
||||
struct ext2fs_node *currroot,
|
||||
struct ext2fs_node **currfound, int *foundtype)
|
||||
int ext4fs_find_file1(const char *currpath, struct ext2fs_node *currroot,
|
||||
struct ext2fs_node **currfound, int *foundtype)
|
||||
{
|
||||
char fpath[strlen(currpath) + 1];
|
||||
char *name = fpath;
|
||||
|
|
|
@ -54,6 +54,8 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos, loff_t len,
|
|||
char *buf, loff_t *actread);
|
||||
int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode,
|
||||
struct ext2fs_node **foundnode, int expecttype);
|
||||
int ext4fs_find_file1(const char *currpath, struct ext2fs_node *currroot,
|
||||
struct ext2fs_node **currfound, int *foundtype);
|
||||
int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
|
||||
struct ext2fs_node **fnode, int *ftype);
|
||||
|
||||
|
|
|
@ -208,11 +208,14 @@ int ext4fs_ls(const char *dirname)
|
|||
|
||||
int ext4fs_exists(const char *filename)
|
||||
{
|
||||
loff_t file_len;
|
||||
int ret;
|
||||
struct ext2fs_node *dirnode = NULL;
|
||||
int filetype;
|
||||
|
||||
ret = ext4fs_open(filename, &file_len);
|
||||
return ret == 0;
|
||||
if (!filename)
|
||||
return 0;
|
||||
|
||||
return ext4fs_find_file1(filename, &ext4fs_root->diropen, &dirnode,
|
||||
&filetype);
|
||||
}
|
||||
|
||||
int ext4fs_size(const char *filename, loff_t *size)
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# (C) Copyright 2003
|
||||
# Pavel Bartusek, Sysgo Real-Time Solutions AG, pba@sysgo.de
|
||||
#
|
||||
|
||||
obj-y := reiserfs.o dev.o mode_string.o
|
|
@ -1,28 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2003 - 2004
|
||||
* Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <common.h>
|
||||
#include <config.h>
|
||||
#include <reiserfs.h>
|
||||
#include <fs_internal.h>
|
||||
#include "reiserfs_private.h"
|
||||
|
||||
static struct blk_desc *reiserfs_blk_desc;
|
||||
static struct disk_partition *part_info;
|
||||
|
||||
|
||||
void reiserfs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info)
|
||||
{
|
||||
reiserfs_blk_desc = rbdd;
|
||||
part_info = info;
|
||||
}
|
||||
|
||||
int reiserfs_devread(int sector, int byte_offset, int byte_len, char *buf)
|
||||
{
|
||||
return fs_devread(reiserfs_blk_desc, part_info, sector, byte_offset,
|
||||
byte_len, buf);
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* mode_string implementation for busybox
|
||||
*
|
||||
* Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
|
||||
*/
|
||||
|
||||
/* Aug 13, 2003
|
||||
* Fix a bug reported by junkio@cox.net involving the mode_chars index.
|
||||
*/
|
||||
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
#if ( S_ISUID != 04000 ) || ( S_ISGID != 02000 ) || ( S_ISVTX != 01000 ) \
|
||||
|| ( S_IRUSR != 00400 ) || ( S_IWUSR != 00200 ) || ( S_IXUSR != 00100 ) \
|
||||
|| ( S_IRGRP != 00040 ) || ( S_IWGRP != 00020 ) || ( S_IXGRP != 00010 ) \
|
||||
|| ( S_IROTH != 00004 ) || ( S_IWOTH != 00002 ) || ( S_IXOTH != 00001 )
|
||||
#error permission bitflag value assumption(s) violated!
|
||||
#endif
|
||||
|
||||
#if ( S_IFSOCK!= 0140000 ) || ( S_IFLNK != 0120000 ) \
|
||||
|| ( S_IFREG != 0100000 ) || ( S_IFBLK != 0060000 ) \
|
||||
|| ( S_IFDIR != 0040000 ) || ( S_IFCHR != 0020000 ) \
|
||||
|| ( S_IFIFO != 0010000 )
|
||||
#warning mode type bitflag value assumption(s) violated! falling back to larger version
|
||||
|
||||
#if (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX) == 07777
|
||||
#undef mode_t
|
||||
#define mode_t unsigned short
|
||||
#endif
|
||||
|
||||
static const mode_t mode_flags[] = {
|
||||
S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID,
|
||||
S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID,
|
||||
S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX
|
||||
};
|
||||
|
||||
/* The static const char arrays below are duplicated for the two cases
|
||||
* because moving them ahead of the mode_flags declaration cause a text
|
||||
* size increase with the gcc version I'm using. */
|
||||
|
||||
/* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C',
|
||||
* and 'B' types don't appear to be available on linux. So I removed them. */
|
||||
static const char type_chars[16] = "?pc?d?b?-?l?s???";
|
||||
/* 0123456789abcdef */
|
||||
static const char mode_chars[7] = "rwxSTst";
|
||||
|
||||
const char *bb_mode_string(int mode)
|
||||
{
|
||||
static char buf[12];
|
||||
char *p = buf;
|
||||
|
||||
int i, j, k;
|
||||
|
||||
*p = type_chars[ (mode >> 12) & 0xf ];
|
||||
i = 0;
|
||||
do {
|
||||
j = k = 0;
|
||||
do {
|
||||
*++p = '-';
|
||||
if (mode & mode_flags[i+j]) {
|
||||
*p = mode_chars[j];
|
||||
k = j;
|
||||
}
|
||||
} while (++j < 3);
|
||||
if (mode & mode_flags[i+j]) {
|
||||
*p = mode_chars[3 + (k & 2) + ((i&8) >> 3)];
|
||||
}
|
||||
i += 4;
|
||||
} while (i < 12);
|
||||
|
||||
/* Note: We don't bother with nul termination because bss initialization
|
||||
* should have taken care of that for us. If the user scribbled in buf
|
||||
* memory, they deserve whatever happens. But we'll at least assert. */
|
||||
if (buf[10] != 0) return NULL;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C',
|
||||
* and 'B' types don't appear to be available on linux. So I removed them. */
|
||||
static const char type_chars[16] = "?pc?d?b?-?l?s???";
|
||||
/* 0123456789abcdef */
|
||||
static const char mode_chars[7] = "rwxSTst";
|
||||
|
||||
const char *bb_mode_string(int mode)
|
||||
{
|
||||
static char buf[12];
|
||||
char *p = buf;
|
||||
|
||||
int i, j, k, m;
|
||||
|
||||
*p = type_chars[ (mode >> 12) & 0xf ];
|
||||
i = 0;
|
||||
m = 0400;
|
||||
do {
|
||||
j = k = 0;
|
||||
do {
|
||||
*++p = '-';
|
||||
if (mode & m) {
|
||||
*p = mode_chars[j];
|
||||
k = j;
|
||||
}
|
||||
m >>= 1;
|
||||
} while (++j < 3);
|
||||
++i;
|
||||
if (mode & (010000 >> i)) {
|
||||
*p = mode_chars[3 + (k & 2) + (i == 3)];
|
||||
}
|
||||
} while (i < 3);
|
||||
|
||||
/* Note: We don't bother with nul termination because bss initialization
|
||||
* should have taken care of that for us. If the user scribbled in buf
|
||||
* memory, they deserve whatever happens. But we'll at least assert. */
|
||||
if (buf[10] != 0) return NULL;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,971 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
|
||||
*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* (C) Copyright 2003 - 2004
|
||||
* Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/* An implementation for the ReiserFS filesystem ported from GRUB.
|
||||
* Some parts of this code (mainly the structures and defines) are
|
||||
* from the original reiser fs code, as found in the linux kernel.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/time.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <reiserfs.h>
|
||||
|
||||
#include "reiserfs_private.h"
|
||||
|
||||
#undef REISERDEBUG
|
||||
|
||||
/* Some parts of this code (mainly the structures and defines) are
|
||||
* from the original reiser fs code, as found in the linux kernel.
|
||||
*/
|
||||
|
||||
static char fsys_buf[FSYS_BUFLEN];
|
||||
static reiserfs_error_t errnum = ERR_NONE;
|
||||
static int print_possibilities;
|
||||
static unsigned int filepos, filemax;
|
||||
|
||||
static int
|
||||
substring (const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 == *s2)
|
||||
{
|
||||
/* The strings match exactly. */
|
||||
if (! *(s1++))
|
||||
return 0;
|
||||
s2 ++;
|
||||
}
|
||||
|
||||
/* S1 is a substring of S2. */
|
||||
if (*s1 == 0)
|
||||
return -1;
|
||||
|
||||
/* S1 isn't a substring. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void sd_print_item (struct item_head * ih, char * item)
|
||||
{
|
||||
char filetime[30];
|
||||
time_t ttime;
|
||||
|
||||
if (stat_data_v1 (ih)) {
|
||||
struct stat_data_v1 * sd = (struct stat_data_v1 *)item;
|
||||
ttime = sd_v1_mtime(sd);
|
||||
ctime_r(&ttime, filetime);
|
||||
printf ("%-10s %4hd %6d %6d %9d %24.24s",
|
||||
bb_mode_string(sd_v1_mode(sd)), sd_v1_nlink(sd),sd_v1_uid(sd), sd_v1_gid(sd),
|
||||
sd_v1_size(sd), filetime);
|
||||
} else {
|
||||
struct stat_data * sd = (struct stat_data *)item;
|
||||
ttime = sd_v2_mtime(sd);
|
||||
ctime_r(&ttime, filetime);
|
||||
printf ("%-10s %4d %6d %6d %9d %24.24s",
|
||||
bb_mode_string(sd_v2_mode(sd)), sd_v2_nlink(sd),sd_v2_uid(sd),sd_v2_gid(sd),
|
||||
(__u32) sd_v2_size(sd), filetime);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
journal_read (int block, int len, char *buffer)
|
||||
{
|
||||
return reiserfs_devread ((INFO->journal_block + block) << INFO->blocksize_shift,
|
||||
0, len, buffer);
|
||||
}
|
||||
|
||||
/* Read a block from ReiserFS file system, taking the journal into
|
||||
* account. If the block nr is in the journal, the block from the
|
||||
* journal taken.
|
||||
*/
|
||||
static int
|
||||
block_read (unsigned int blockNr, int start, int len, char *buffer)
|
||||
{
|
||||
int transactions = INFO->journal_transactions;
|
||||
int desc_block = INFO->journal_first_desc;
|
||||
int journal_mask = INFO->journal_block_count - 1;
|
||||
int translatedNr = blockNr;
|
||||
__u32 *journal_table = JOURNAL_START;
|
||||
while (transactions-- > 0)
|
||||
{
|
||||
int i = 0;
|
||||
int j_len;
|
||||
if (__le32_to_cpu(*journal_table) != 0xffffffff)
|
||||
{
|
||||
/* Search for the blockNr in cached journal */
|
||||
j_len = __le32_to_cpu(*journal_table++);
|
||||
while (i++ < j_len)
|
||||
{
|
||||
if (__le32_to_cpu(*journal_table++) == blockNr)
|
||||
{
|
||||
journal_table += j_len - i;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is the end of cached journal marker. The remaining
|
||||
* transactions are still on disk.
|
||||
*/
|
||||
struct reiserfs_journal_desc desc;
|
||||
struct reiserfs_journal_commit commit;
|
||||
|
||||
if (! journal_read (desc_block, sizeof (desc), (char *) &desc))
|
||||
return 0;
|
||||
|
||||
j_len = __le32_to_cpu(desc.j_len);
|
||||
while (i < j_len && i < JOURNAL_TRANS_HALF)
|
||||
if (__le32_to_cpu(desc.j_realblock[i++]) == blockNr)
|
||||
goto found;
|
||||
|
||||
if (j_len >= JOURNAL_TRANS_HALF)
|
||||
{
|
||||
int commit_block = (desc_block + 1 + j_len) & journal_mask;
|
||||
if (! journal_read (commit_block,
|
||||
sizeof (commit), (char *) &commit))
|
||||
return 0;
|
||||
while (i < j_len)
|
||||
if (__le32_to_cpu(commit.j_realblock[i++ - JOURNAL_TRANS_HALF]) == blockNr)
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
goto not_found;
|
||||
|
||||
found:
|
||||
translatedNr = INFO->journal_block + ((desc_block + i) & journal_mask);
|
||||
#ifdef REISERDEBUG
|
||||
printf ("block_read: block %d is mapped to journal block %d.\n",
|
||||
blockNr, translatedNr - INFO->journal_block);
|
||||
#endif
|
||||
/* We must continue the search, as this block may be overwritten
|
||||
* in later transactions.
|
||||
*/
|
||||
not_found:
|
||||
desc_block = (desc_block + 2 + j_len) & journal_mask;
|
||||
}
|
||||
return reiserfs_devread (translatedNr << INFO->blocksize_shift, start, len, buffer);
|
||||
}
|
||||
|
||||
/* Init the journal data structure. We try to cache as much as
|
||||
* possible in the JOURNAL_START-JOURNAL_END space, but if it is full
|
||||
* we can still read the rest from the disk on demand.
|
||||
*
|
||||
* The first number of valid transactions and the descriptor block of the
|
||||
* first valid transaction are held in INFO. The transactions are all
|
||||
* adjacent, but we must take care of the journal wrap around.
|
||||
*/
|
||||
static int
|
||||
journal_init (void)
|
||||
{
|
||||
unsigned int block_count = INFO->journal_block_count;
|
||||
unsigned int desc_block;
|
||||
unsigned int commit_block;
|
||||
unsigned int next_trans_id;
|
||||
struct reiserfs_journal_header header;
|
||||
struct reiserfs_journal_desc desc;
|
||||
struct reiserfs_journal_commit commit;
|
||||
__u32 *journal_table = JOURNAL_START;
|
||||
|
||||
journal_read (block_count, sizeof (header), (char *) &header);
|
||||
desc_block = __le32_to_cpu(header.j_first_unflushed_offset);
|
||||
if (desc_block >= block_count)
|
||||
return 0;
|
||||
|
||||
INFO->journal_first_desc = desc_block;
|
||||
next_trans_id = __le32_to_cpu(header.j_last_flush_trans_id) + 1;
|
||||
|
||||
#ifdef REISERDEBUG
|
||||
printf ("journal_init: last flushed %d\n",
|
||||
__le32_to_cpu(header.j_last_flush_trans_id));
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
journal_read (desc_block, sizeof (desc), (char *) &desc);
|
||||
if (substring (JOURNAL_DESC_MAGIC, desc.j_magic) > 0
|
||||
|| __le32_to_cpu(desc.j_trans_id) != next_trans_id
|
||||
|| __le32_to_cpu(desc.j_mount_id) != __le32_to_cpu(header.j_mount_id))
|
||||
/* no more valid transactions */
|
||||
break;
|
||||
|
||||
commit_block = (desc_block + __le32_to_cpu(desc.j_len) + 1) & (block_count - 1);
|
||||
journal_read (commit_block, sizeof (commit), (char *) &commit);
|
||||
if (__le32_to_cpu(desc.j_trans_id) != commit.j_trans_id
|
||||
|| __le32_to_cpu(desc.j_len) != __le32_to_cpu(commit.j_len))
|
||||
/* no more valid transactions */
|
||||
break;
|
||||
|
||||
#ifdef REISERDEBUG
|
||||
printf ("Found valid transaction %d/%d at %d.\n",
|
||||
__le32_to_cpu(desc.j_trans_id), __le32_to_cpu(desc.j_mount_id), desc_block);
|
||||
#endif
|
||||
|
||||
next_trans_id++;
|
||||
if (journal_table < JOURNAL_END)
|
||||
{
|
||||
if ((journal_table + 1 + __le32_to_cpu(desc.j_len)) >= JOURNAL_END)
|
||||
{
|
||||
/* The table is almost full; mark the end of the cached
|
||||
* journal.*/
|
||||
*journal_table = __cpu_to_le32(0xffffffff);
|
||||
journal_table = JOURNAL_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int i;
|
||||
/* Cache the length and the realblock numbers in the table.
|
||||
* The block number of descriptor can easily be computed.
|
||||
* and need not to be stored here.
|
||||
*/
|
||||
|
||||
/* both are in the little endian format */
|
||||
*journal_table++ = desc.j_len;
|
||||
for (i = 0; i < __le32_to_cpu(desc.j_len) && i < JOURNAL_TRANS_HALF; i++)
|
||||
{
|
||||
/* both are in the little endian format */
|
||||
*journal_table++ = desc.j_realblock[i];
|
||||
#ifdef REISERDEBUG
|
||||
printf ("block %d is in journal %d.\n",
|
||||
__le32_to_cpu(desc.j_realblock[i]), desc_block);
|
||||
#endif
|
||||
}
|
||||
for ( ; i < __le32_to_cpu(desc.j_len); i++)
|
||||
{
|
||||
/* both are in the little endian format */
|
||||
*journal_table++ = commit.j_realblock[i-JOURNAL_TRANS_HALF];
|
||||
#ifdef REISERDEBUG
|
||||
printf ("block %d is in journal %d.\n",
|
||||
__le32_to_cpu(commit.j_realblock[i-JOURNAL_TRANS_HALF]),
|
||||
desc_block);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
desc_block = (commit_block + 1) & (block_count - 1);
|
||||
}
|
||||
#ifdef REISERDEBUG
|
||||
printf ("Transaction %d/%d at %d isn't valid.\n",
|
||||
__le32_to_cpu(desc.j_trans_id), __le32_to_cpu(desc.j_mount_id), desc_block);
|
||||
#endif
|
||||
|
||||
INFO->journal_transactions
|
||||
= next_trans_id - __le32_to_cpu(header.j_last_flush_trans_id) - 1;
|
||||
return errnum == 0;
|
||||
}
|
||||
|
||||
/* check filesystem types and read superblock into memory buffer */
|
||||
int
|
||||
reiserfs_mount (unsigned part_length)
|
||||
{
|
||||
struct reiserfs_super_block super;
|
||||
int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
|
||||
char *cache;
|
||||
|
||||
if (part_length < superblock + (sizeof (super) >> SECTOR_BITS)
|
||||
|| ! reiserfs_devread (superblock, 0, sizeof (struct reiserfs_super_block),
|
||||
(char *) &super)
|
||||
|| (substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) > 0
|
||||
&& substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0
|
||||
&& substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0)
|
||||
|| (/* check that this is not a copy inside the journal log */
|
||||
sb_journal_block(&super) * sb_blocksize(&super)
|
||||
<= REISERFS_DISK_OFFSET_IN_BYTES))
|
||||
{
|
||||
/* Try old super block position */
|
||||
superblock = REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
|
||||
if (part_length < superblock + (sizeof (super) >> SECTOR_BITS)
|
||||
|| ! reiserfs_devread (superblock, 0, sizeof (struct reiserfs_super_block),
|
||||
(char *) &super))
|
||||
return 0;
|
||||
|
||||
if (substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0
|
||||
&& substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0)
|
||||
{
|
||||
/* pre journaling super block ? */
|
||||
if (substring (REISERFS_SUPER_MAGIC_STRING,
|
||||
(char*) ((int) &super + 20)) > 0)
|
||||
return 0;
|
||||
|
||||
set_sb_blocksize(&super, REISERFS_OLD_BLOCKSIZE);
|
||||
set_sb_journal_block(&super, 0);
|
||||
set_sb_version(&super, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* check the version number. */
|
||||
if (sb_version(&super) > REISERFS_MAX_SUPPORTED_VERSION)
|
||||
return 0;
|
||||
|
||||
INFO->version = sb_version(&super);
|
||||
INFO->blocksize = sb_blocksize(&super);
|
||||
INFO->fullblocksize_shift = log2 (sb_blocksize(&super));
|
||||
INFO->blocksize_shift = INFO->fullblocksize_shift - SECTOR_BITS;
|
||||
INFO->cached_slots =
|
||||
(FSYSREISER_CACHE_SIZE >> INFO->fullblocksize_shift) - 1;
|
||||
|
||||
#ifdef REISERDEBUG
|
||||
printf ("reiserfs_mount: version=%d, blocksize=%d\n",
|
||||
INFO->version, INFO->blocksize);
|
||||
#endif /* REISERDEBUG */
|
||||
|
||||
/* Clear node cache. */
|
||||
memset (INFO->blocks, 0, sizeof (INFO->blocks));
|
||||
|
||||
if (sb_blocksize(&super) < FSYSREISER_MIN_BLOCKSIZE
|
||||
|| sb_blocksize(&super) > FSYSREISER_MAX_BLOCKSIZE
|
||||
|| (SECTOR_SIZE << INFO->blocksize_shift) != sb_blocksize(&super))
|
||||
return 0;
|
||||
|
||||
/* Initialize journal code. If something fails we end with zero
|
||||
* journal_transactions, so we don't access the journal at all.
|
||||
*/
|
||||
INFO->journal_transactions = 0;
|
||||
if (sb_journal_block(&super) != 0 && super.s_journal_dev == 0)
|
||||
{
|
||||
INFO->journal_block = sb_journal_block(&super);
|
||||
INFO->journal_block_count = sb_journal_size(&super);
|
||||
if (is_power_of_two (INFO->journal_block_count))
|
||||
journal_init ();
|
||||
|
||||
/* Read in super block again, maybe it is in the journal */
|
||||
block_read (superblock >> INFO->blocksize_shift,
|
||||
0, sizeof (struct reiserfs_super_block), (char *) &super);
|
||||
}
|
||||
|
||||
if (! block_read (sb_root_block(&super), 0, INFO->blocksize, (char*) ROOT))
|
||||
return 0;
|
||||
|
||||
cache = ROOT;
|
||||
INFO->tree_depth = __le16_to_cpu(BLOCKHEAD (cache)->blk_level);
|
||||
|
||||
#ifdef REISERDEBUG
|
||||
printf ("root read_in: block=%d, depth=%d\n",
|
||||
sb_root_block(&super), INFO->tree_depth);
|
||||
#endif /* REISERDEBUG */
|
||||
|
||||
if (INFO->tree_depth >= MAX_HEIGHT)
|
||||
return 0;
|
||||
if (INFO->tree_depth == DISK_LEAF_NODE_LEVEL)
|
||||
{
|
||||
/* There is only one node in the whole filesystem,
|
||||
* which is simultanously leaf and root */
|
||||
memcpy (LEAF, ROOT, INFO->blocksize);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***************** TREE ACCESSING METHODS *****************************/
|
||||
|
||||
/* I assume you are familiar with the ReiserFS tree, if not go to
|
||||
* http://www.namesys.com/content_table.html
|
||||
*
|
||||
* My tree node cache is organized as following
|
||||
* 0 ROOT node
|
||||
* 1 LEAF node (if the ROOT is also a LEAF it is copied here
|
||||
* 2-n other nodes on current path from bottom to top.
|
||||
* if there is not enough space in the cache, the top most are
|
||||
* omitted.
|
||||
*
|
||||
* I have only two methods to find a key in the tree:
|
||||
* search_stat(dir_id, objectid) searches for the stat entry (always
|
||||
* the first entry) of an object.
|
||||
* next_key() gets the next key in tree order.
|
||||
*
|
||||
* This means, that I can only sequential reads of files are
|
||||
* efficient, but this really doesn't hurt for grub.
|
||||
*/
|
||||
|
||||
/* Read in the node at the current path and depth into the node cache.
|
||||
* You must set INFO->blocks[depth] before.
|
||||
*/
|
||||
static char *
|
||||
read_tree_node (unsigned int blockNr, int depth)
|
||||
{
|
||||
char* cache = CACHE(depth);
|
||||
int num_cached = INFO->cached_slots;
|
||||
if (depth < num_cached)
|
||||
{
|
||||
/* This is the cached part of the path. Check if same block is
|
||||
* needed.
|
||||
*/
|
||||
if (blockNr == INFO->blocks[depth])
|
||||
return cache;
|
||||
}
|
||||
else
|
||||
cache = CACHE(num_cached);
|
||||
|
||||
#ifdef REISERDEBUG
|
||||
printf (" next read_in: block=%d (depth=%d)\n",
|
||||
blockNr, depth);
|
||||
#endif /* REISERDEBUG */
|
||||
if (! block_read (blockNr, 0, INFO->blocksize, cache))
|
||||
return 0;
|
||||
/* Make sure it has the right node level */
|
||||
if (__le16_to_cpu(BLOCKHEAD (cache)->blk_level) != depth)
|
||||
{
|
||||
errnum = ERR_FSYS_CORRUPT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
INFO->blocks[depth] = blockNr;
|
||||
return cache;
|
||||
}
|
||||
|
||||
/* Get the next key, i.e. the key following the last retrieved key in
|
||||
* tree order. INFO->current_ih and
|
||||
* INFO->current_info are adapted accordingly. */
|
||||
static int
|
||||
next_key (void)
|
||||
{
|
||||
int depth;
|
||||
struct item_head *ih = INFO->current_ih + 1;
|
||||
char *cache;
|
||||
|
||||
#ifdef REISERDEBUG
|
||||
printf ("next_key:\n old ih: key %d:%d:%d:%d version:%d\n",
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset),
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness),
|
||||
__le16_to_cpu(INFO->current_ih->ih_version));
|
||||
#endif /* REISERDEBUG */
|
||||
|
||||
if (ih == &ITEMHEAD[__le16_to_cpu(BLOCKHEAD (LEAF)->blk_nr_item)])
|
||||
{
|
||||
depth = DISK_LEAF_NODE_LEVEL;
|
||||
/* The last item, was the last in the leaf node.
|
||||
* Read in the next block
|
||||
*/
|
||||
do
|
||||
{
|
||||
if (depth == INFO->tree_depth)
|
||||
{
|
||||
/* There are no more keys at all.
|
||||
* Return a dummy item with MAX_KEY */
|
||||
ih = (struct item_head *) &BLOCKHEAD (LEAF)->blk_right_delim_key;
|
||||
goto found;
|
||||
}
|
||||
depth++;
|
||||
#ifdef REISERDEBUG
|
||||
printf (" depth=%d, i=%d\n", depth, INFO->next_key_nr[depth]);
|
||||
#endif /* REISERDEBUG */
|
||||
}
|
||||
while (INFO->next_key_nr[depth] == 0);
|
||||
|
||||
if (depth == INFO->tree_depth)
|
||||
cache = ROOT;
|
||||
else if (depth <= INFO->cached_slots)
|
||||
cache = CACHE (depth);
|
||||
else
|
||||
{
|
||||
cache = read_tree_node (INFO->blocks[depth], depth);
|
||||
if (! cache)
|
||||
return 0;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
int nr_item = __le16_to_cpu(BLOCKHEAD (cache)->blk_nr_item);
|
||||
int key_nr = INFO->next_key_nr[depth]++;
|
||||
#ifdef REISERDEBUG
|
||||
printf (" depth=%d, i=%d/%d\n", depth, key_nr, nr_item);
|
||||
#endif /* REISERDEBUG */
|
||||
if (key_nr == nr_item)
|
||||
/* This is the last item in this block, set the next_key_nr to 0 */
|
||||
INFO->next_key_nr[depth] = 0;
|
||||
|
||||
cache = read_tree_node (dc_block_number(&(DC (cache)[key_nr])), --depth);
|
||||
if (! cache)
|
||||
return 0;
|
||||
}
|
||||
while (depth > DISK_LEAF_NODE_LEVEL);
|
||||
|
||||
ih = ITEMHEAD;
|
||||
}
|
||||
found:
|
||||
INFO->current_ih = ih;
|
||||
INFO->current_item = &LEAF[__le16_to_cpu(ih->ih_item_location)];
|
||||
#ifdef REISERDEBUG
|
||||
printf (" new ih: key %d:%d:%d:%d version:%d\n",
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset),
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness),
|
||||
__le16_to_cpu(INFO->current_ih->ih_version));
|
||||
#endif /* REISERDEBUG */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* preconditions: reiserfs_mount already executed, therefore
|
||||
* INFO block is valid
|
||||
* returns: 0 if error (errnum is set),
|
||||
* nonzero iff we were able to find the key successfully.
|
||||
* postconditions: on a nonzero return, the current_ih and
|
||||
* current_item fields describe the key that equals the
|
||||
* searched key. INFO->next_key contains the next key after
|
||||
* the searched key.
|
||||
* side effects: messes around with the cache.
|
||||
*/
|
||||
static int
|
||||
search_stat (__u32 dir_id, __u32 objectid)
|
||||
{
|
||||
char *cache;
|
||||
int depth;
|
||||
int nr_item;
|
||||
int i;
|
||||
struct item_head *ih;
|
||||
#ifdef REISERDEBUG
|
||||
printf ("search_stat:\n key %d:%d:0:0\n", dir_id, objectid);
|
||||
#endif /* REISERDEBUG */
|
||||
|
||||
depth = INFO->tree_depth;
|
||||
cache = ROOT;
|
||||
|
||||
while (depth > DISK_LEAF_NODE_LEVEL)
|
||||
{
|
||||
struct key *key;
|
||||
nr_item = __le16_to_cpu(BLOCKHEAD (cache)->blk_nr_item);
|
||||
|
||||
key = KEY (cache);
|
||||
|
||||
for (i = 0; i < nr_item; i++)
|
||||
{
|
||||
if (__le32_to_cpu(key->k_dir_id) > dir_id
|
||||
|| (__le32_to_cpu(key->k_dir_id) == dir_id
|
||||
&& (__le32_to_cpu(key->k_objectid) > objectid
|
||||
|| (__le32_to_cpu(key->k_objectid) == objectid
|
||||
&& (__le32_to_cpu(key->u.v1.k_offset)
|
||||
| __le32_to_cpu(key->u.v1.k_uniqueness)) > 0))))
|
||||
break;
|
||||
key++;
|
||||
}
|
||||
|
||||
#ifdef REISERDEBUG
|
||||
printf (" depth=%d, i=%d/%d\n", depth, i, nr_item);
|
||||
#endif /* REISERDEBUG */
|
||||
INFO->next_key_nr[depth] = (i == nr_item) ? 0 : i+1;
|
||||
cache = read_tree_node (dc_block_number(&(DC (cache)[i])), --depth);
|
||||
if (! cache)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* cache == LEAF */
|
||||
nr_item = __le16_to_cpu(BLOCKHEAD (LEAF)->blk_nr_item);
|
||||
ih = ITEMHEAD;
|
||||
for (i = 0; i < nr_item; i++)
|
||||
{
|
||||
if (__le32_to_cpu(ih->ih_key.k_dir_id) == dir_id
|
||||
&& __le32_to_cpu(ih->ih_key.k_objectid) == objectid
|
||||
&& __le32_to_cpu(ih->ih_key.u.v1.k_offset) == 0
|
||||
&& __le32_to_cpu(ih->ih_key.u.v1.k_uniqueness) == 0)
|
||||
{
|
||||
#ifdef REISERDEBUG
|
||||
printf (" depth=%d, i=%d/%d\n", depth, i, nr_item);
|
||||
#endif /* REISERDEBUG */
|
||||
INFO->current_ih = ih;
|
||||
INFO->current_item = &LEAF[__le16_to_cpu(ih->ih_item_location)];
|
||||
return 1;
|
||||
}
|
||||
ih++;
|
||||
}
|
||||
errnum = ERR_FSYS_CORRUPT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
reiserfs_read (char *buf, unsigned len)
|
||||
{
|
||||
unsigned int blocksize;
|
||||
unsigned int offset;
|
||||
unsigned int to_read;
|
||||
char *prev_buf = buf;
|
||||
|
||||
#ifdef REISERDEBUG
|
||||
printf ("reiserfs_read: filepos=%d len=%d, offset=%Lx\n",
|
||||
filepos, len, (__u64) IH_KEY_OFFSET (INFO->current_ih) - 1);
|
||||
#endif /* REISERDEBUG */
|
||||
|
||||
if (__le32_to_cpu(INFO->current_ih->ih_key.k_objectid) != INFO->fileinfo.k_objectid
|
||||
|| IH_KEY_OFFSET (INFO->current_ih) > filepos + 1)
|
||||
{
|
||||
search_stat (INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid);
|
||||
goto get_next_key;
|
||||
}
|
||||
|
||||
while (! errnum)
|
||||
{
|
||||
if (__le32_to_cpu(INFO->current_ih->ih_key.k_objectid) != INFO->fileinfo.k_objectid) {
|
||||
break;
|
||||
}
|
||||
|
||||
offset = filepos - IH_KEY_OFFSET (INFO->current_ih) + 1;
|
||||
blocksize = __le16_to_cpu(INFO->current_ih->ih_item_len);
|
||||
|
||||
#ifdef REISERDEBUG
|
||||
printf (" loop: filepos=%d len=%d, offset=%d blocksize=%d\n",
|
||||
filepos, len, offset, blocksize);
|
||||
#endif /* REISERDEBUG */
|
||||
|
||||
if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_DIRECT)
|
||||
&& offset < blocksize)
|
||||
{
|
||||
#ifdef REISERDEBUG
|
||||
printf ("direct_read: offset=%d, blocksize=%d\n",
|
||||
offset, blocksize);
|
||||
#endif /* REISERDEBUG */
|
||||
to_read = blocksize - offset;
|
||||
if (to_read > len)
|
||||
to_read = len;
|
||||
|
||||
memcpy (buf, INFO->current_item + offset, to_read);
|
||||
goto update_buf_len;
|
||||
}
|
||||
else if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_INDIRECT))
|
||||
{
|
||||
blocksize = (blocksize >> 2) << INFO->fullblocksize_shift;
|
||||
#ifdef REISERDEBUG
|
||||
printf ("indirect_read: offset=%d, blocksize=%d\n",
|
||||
offset, blocksize);
|
||||
#endif /* REISERDEBUG */
|
||||
|
||||
while (offset < blocksize)
|
||||
{
|
||||
__u32 blocknr = __le32_to_cpu(((__u32 *) INFO->current_item)
|
||||
[offset >> INFO->fullblocksize_shift]);
|
||||
int blk_offset = offset & (INFO->blocksize-1);
|
||||
to_read = INFO->blocksize - blk_offset;
|
||||
if (to_read > len)
|
||||
to_read = len;
|
||||
|
||||
/* Journal is only for meta data. Data blocks can be read
|
||||
* directly without using block_read
|
||||
*/
|
||||
reiserfs_devread (blocknr << INFO->blocksize_shift,
|
||||
blk_offset, to_read, buf);
|
||||
update_buf_len:
|
||||
len -= to_read;
|
||||
buf += to_read;
|
||||
offset += to_read;
|
||||
filepos += to_read;
|
||||
if (len == 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
get_next_key:
|
||||
next_key ();
|
||||
}
|
||||
done:
|
||||
return errnum ? 0 : buf - prev_buf;
|
||||
}
|
||||
|
||||
|
||||
/* preconditions: reiserfs_mount already executed, therefore
|
||||
* INFO block is valid
|
||||
* returns: 0 if error, nonzero iff we were able to find the file successfully
|
||||
* postconditions: on a nonzero return, INFO->fileinfo contains the info
|
||||
* of the file we were trying to look up, filepos is 0 and filemax is
|
||||
* the size of the file.
|
||||
*/
|
||||
static int
|
||||
reiserfs_dir (char *dirname)
|
||||
{
|
||||
struct reiserfs_de_head *de_head;
|
||||
char *rest, ch;
|
||||
__u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;
|
||||
#ifndef STAGE1_5
|
||||
int do_possibilities = 0;
|
||||
#endif /* ! STAGE1_5 */
|
||||
char linkbuf[PATH_MAX]; /* buffer for following symbolic links */
|
||||
int link_count = 0;
|
||||
int mode;
|
||||
|
||||
dir_id = REISERFS_ROOT_PARENT_OBJECTID;
|
||||
objectid = REISERFS_ROOT_OBJECTID;
|
||||
|
||||
while (1)
|
||||
{
|
||||
#ifdef REISERDEBUG
|
||||
printf ("dirname=%s\n", dirname);
|
||||
#endif /* REISERDEBUG */
|
||||
|
||||
/* Search for the stat info first. */
|
||||
if (! search_stat (dir_id, objectid))
|
||||
return 0;
|
||||
|
||||
#ifdef REISERDEBUG
|
||||
printf ("sd_mode=%x sd_size=%d\n",
|
||||
stat_data_v1(INFO->current_ih) ? sd_v1_mode((struct stat_data_v1 *) INFO->current_item) :
|
||||
sd_v2_mode((struct stat_data *) (INFO->current_item)),
|
||||
stat_data_v1(INFO->current_ih) ? sd_v1_size((struct stat_data_v1 *) INFO->current_item) :
|
||||
sd_v2_size((struct stat_data *) INFO->current_item)
|
||||
);
|
||||
|
||||
#endif /* REISERDEBUG */
|
||||
mode = stat_data_v1(INFO->current_ih) ?
|
||||
sd_v1_mode((struct stat_data_v1 *) INFO->current_item) :
|
||||
sd_v2_mode((struct stat_data *) INFO->current_item);
|
||||
|
||||
/* If we've got a symbolic link, then chase it. */
|
||||
if (S_ISLNK (mode))
|
||||
{
|
||||
unsigned int len;
|
||||
if (++link_count > MAX_LINK_COUNT)
|
||||
{
|
||||
errnum = ERR_SYMLINK_LOOP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the symlink size. */
|
||||
filemax = stat_data_v1(INFO->current_ih) ?
|
||||
sd_v1_size((struct stat_data_v1 *) INFO->current_item) :
|
||||
sd_v2_size((struct stat_data *) INFO->current_item);
|
||||
|
||||
/* Find out how long our remaining name is. */
|
||||
len = 0;
|
||||
while (dirname[len] && !isspace (dirname[len]))
|
||||
len++;
|
||||
|
||||
if (filemax + len > sizeof (linkbuf) - 1)
|
||||
{
|
||||
errnum = ERR_FILELENGTH;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy the remaining name to the end of the symlink data.
|
||||
Note that DIRNAME and LINKBUF may overlap! */
|
||||
memmove (linkbuf + filemax, dirname, len+1);
|
||||
|
||||
INFO->fileinfo.k_dir_id = dir_id;
|
||||
INFO->fileinfo.k_objectid = objectid;
|
||||
filepos = 0;
|
||||
if (! next_key ()
|
||||
|| reiserfs_read (linkbuf, filemax) != filemax)
|
||||
{
|
||||
if (! errnum)
|
||||
errnum = ERR_FSYS_CORRUPT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef REISERDEBUG
|
||||
printf ("symlink=%s\n", linkbuf);
|
||||
#endif /* REISERDEBUG */
|
||||
|
||||
dirname = linkbuf;
|
||||
if (*dirname == '/')
|
||||
{
|
||||
/* It's an absolute link, so look it up in root. */
|
||||
dir_id = REISERFS_ROOT_PARENT_OBJECTID;
|
||||
objectid = REISERFS_ROOT_OBJECTID;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Relative, so look it up in our parent directory. */
|
||||
dir_id = parent_dir_id;
|
||||
objectid = parent_objectid;
|
||||
}
|
||||
|
||||
/* Now lookup the new name. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if we have a real file (and we're not just printing possibilities),
|
||||
then this is where we want to exit */
|
||||
|
||||
if (! *dirname || isspace (*dirname))
|
||||
{
|
||||
if (! S_ISREG (mode))
|
||||
{
|
||||
errnum = ERR_BAD_FILETYPE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
filepos = 0;
|
||||
filemax = stat_data_v1(INFO->current_ih) ?
|
||||
sd_v1_size((struct stat_data_v1 *) INFO->current_item) :
|
||||
sd_v2_size((struct stat_data *) INFO->current_item);
|
||||
#if 0
|
||||
/* If this is a new stat data and size is > 4GB set filemax to
|
||||
* maximum
|
||||
*/
|
||||
if (__le16_to_cpu(INFO->current_ih->ih_version) == ITEM_VERSION_2
|
||||
&& sd_size_hi((struct stat_data *) INFO->current_item) > 0)
|
||||
filemax = 0xffffffff;
|
||||
#endif
|
||||
INFO->fileinfo.k_dir_id = dir_id;
|
||||
INFO->fileinfo.k_objectid = objectid;
|
||||
return next_key ();
|
||||
}
|
||||
|
||||
/* continue with the file/directory name interpretation */
|
||||
while (*dirname == '/')
|
||||
dirname++;
|
||||
if (! S_ISDIR (mode))
|
||||
{
|
||||
errnum = ERR_BAD_FILETYPE;
|
||||
return 0;
|
||||
}
|
||||
for (rest = dirname; (ch = *rest) && ! isspace (ch) && ch != '/'; rest++);
|
||||
*rest = 0;
|
||||
|
||||
# ifndef STAGE1_5
|
||||
if (print_possibilities && ch != '/')
|
||||
do_possibilities = 1;
|
||||
# endif /* ! STAGE1_5 */
|
||||
|
||||
while (1)
|
||||
{
|
||||
char *name_end;
|
||||
int num_entries;
|
||||
|
||||
if (! next_key ())
|
||||
return 0;
|
||||
#ifdef REISERDEBUG
|
||||
printf ("ih: key %d:%d:%d:%d version:%d\n",
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_offset),
|
||||
__le32_to_cpu(INFO->current_ih->ih_key.u.v1.k_uniqueness),
|
||||
__le16_to_cpu(INFO->current_ih->ih_version));
|
||||
#endif /* REISERDEBUG */
|
||||
|
||||
if (__le32_to_cpu(INFO->current_ih->ih_key.k_objectid) != objectid)
|
||||
break;
|
||||
|
||||
name_end = INFO->current_item + __le16_to_cpu(INFO->current_ih->ih_item_len);
|
||||
de_head = (struct reiserfs_de_head *) INFO->current_item;
|
||||
num_entries = __le16_to_cpu(INFO->current_ih->u.ih_entry_count);
|
||||
while (num_entries > 0)
|
||||
{
|
||||
char *filename = INFO->current_item + deh_location(de_head);
|
||||
char tmp = *name_end;
|
||||
if ((deh_state(de_head) & DEH_Visible))
|
||||
{
|
||||
int cmp;
|
||||
/* Directory names in ReiserFS are not null
|
||||
* terminated. We write a temporary 0 behind it.
|
||||
* NOTE: that this may overwrite the first block in
|
||||
* the tree cache. That doesn't hurt as long as we
|
||||
* don't call next_key () in between.
|
||||
*/
|
||||
*name_end = 0;
|
||||
cmp = substring (dirname, filename);
|
||||
*name_end = tmp;
|
||||
# ifndef STAGE1_5
|
||||
if (do_possibilities)
|
||||
{
|
||||
if (cmp <= 0)
|
||||
{
|
||||
char fn[PATH_MAX];
|
||||
struct fsys_reiser_info info_save;
|
||||
|
||||
if (print_possibilities > 0)
|
||||
print_possibilities = -print_possibilities;
|
||||
*name_end = 0;
|
||||
strcpy(fn, filename);
|
||||
*name_end = tmp;
|
||||
|
||||
/* If NAME is "." or "..", do not count it. */
|
||||
if (strcmp (fn, ".") != 0 && strcmp (fn, "..") != 0) {
|
||||
memcpy(&info_save, INFO, sizeof(struct fsys_reiser_info));
|
||||
search_stat (deh_dir_id(de_head), deh_objectid(de_head));
|
||||
sd_print_item(INFO->current_ih, INFO->current_item);
|
||||
printf(" %s\n", fn);
|
||||
search_stat (dir_id, objectid);
|
||||
memcpy(INFO, &info_save, sizeof(struct fsys_reiser_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
# endif /* ! STAGE1_5 */
|
||||
if (cmp == 0)
|
||||
goto found;
|
||||
}
|
||||
/* The beginning of this name marks the end of the next name.
|
||||
*/
|
||||
name_end = filename;
|
||||
de_head++;
|
||||
num_entries--;
|
||||
}
|
||||
}
|
||||
|
||||
# ifndef STAGE1_5
|
||||
if (print_possibilities < 0)
|
||||
return 1;
|
||||
# endif /* ! STAGE1_5 */
|
||||
|
||||
errnum = ERR_FILE_NOT_FOUND;
|
||||
*rest = ch;
|
||||
return 0;
|
||||
|
||||
found:
|
||||
*rest = ch;
|
||||
dirname = rest;
|
||||
|
||||
parent_dir_id = dir_id;
|
||||
parent_objectid = objectid;
|
||||
dir_id = deh_dir_id(de_head);
|
||||
objectid = deh_objectid(de_head);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* U-Boot interface functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* List given directory
|
||||
*
|
||||
* RETURN: 0 - OK, else grub_error_t errnum
|
||||
*/
|
||||
int
|
||||
reiserfs_ls (char *dirname)
|
||||
{
|
||||
char *dir_slash;
|
||||
int res;
|
||||
|
||||
errnum = 0;
|
||||
dir_slash = malloc(strlen(dirname) + 1);
|
||||
if (dir_slash == NULL) {
|
||||
return ERR_NUMBER_OVERFLOW;
|
||||
}
|
||||
strcpy(dir_slash, dirname);
|
||||
/* add "/" to the directory name */
|
||||
strcat(dir_slash, "/");
|
||||
|
||||
print_possibilities = 1;
|
||||
res = reiserfs_dir (dir_slash);
|
||||
free(dir_slash);
|
||||
if (!res || errnum) {
|
||||
return errnum;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open file for reading
|
||||
*
|
||||
* RETURN: >0 - OK, size of opened file
|
||||
* <0 - ERROR -grub_error_t errnum
|
||||
*/
|
||||
int
|
||||
reiserfs_open (char *filename)
|
||||
{
|
||||
/* open the file */
|
||||
errnum = 0;
|
||||
print_possibilities = 0;
|
||||
if (!reiserfs_dir (filename) || errnum) {
|
||||
return -errnum;
|
||||
}
|
||||
return filemax;
|
||||
}
|
|
@ -1,509 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
|
||||
*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* (C) Copyright 2003 - 2004
|
||||
* Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/* An implementation for the ReiserFS filesystem ported from GRUB.
|
||||
* Some parts of this code (mainly the structures and defines) are
|
||||
* from the original reiser fs code, as found in the linux kernel.
|
||||
*/
|
||||
|
||||
#include <compiler.h>
|
||||
|
||||
#ifndef __BYTE_ORDER
|
||||
#if defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
#elif defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN)
|
||||
#define __BYTE_ORDER __BIG_ENDIAN
|
||||
#else
|
||||
#error "unable to define __BYTE_ORDER"
|
||||
#endif
|
||||
#endif /* not __BYTE_ORDER */
|
||||
|
||||
#define FSYS_BUFLEN 0x8000
|
||||
#define FSYS_BUF fsys_buf
|
||||
|
||||
/* This is the new super block of a journaling reiserfs system */
|
||||
struct reiserfs_super_block
|
||||
{
|
||||
__u32 s_block_count; /* blocks count */
|
||||
__u32 s_free_blocks; /* free blocks count */
|
||||
__u32 s_root_block; /* root block number */
|
||||
__u32 s_journal_block; /* journal block number */
|
||||
__u32 s_journal_dev; /* journal device number */
|
||||
__u32 s_journal_size; /* size of the journal on FS creation. used to make sure they don't overflow it */
|
||||
__u32 s_journal_trans_max; /* max number of blocks in a transaction. */
|
||||
__u32 s_journal_magic; /* random value made on fs creation */
|
||||
__u32 s_journal_max_batch; /* max number of blocks to batch into a trans */
|
||||
__u32 s_journal_max_commit_age; /* in seconds, how old can an async commit be */
|
||||
__u32 s_journal_max_trans_age; /* in seconds, how old can a transaction be */
|
||||
__u16 s_blocksize; /* block size */
|
||||
__u16 s_oid_maxsize; /* max size of object id array */
|
||||
__u16 s_oid_cursize; /* current size of object id array */
|
||||
__u16 s_state; /* valid or error */
|
||||
char s_magic[16]; /* reiserfs magic string indicates that file system is reiserfs */
|
||||
__u16 s_tree_height; /* height of disk tree */
|
||||
__u16 s_bmap_nr; /* amount of bitmap blocks needed to address each block of file system */
|
||||
__u16 s_version;
|
||||
char s_unused[128]; /* zero filled by mkreiserfs */
|
||||
};
|
||||
|
||||
|
||||
#define sb_root_block(sbp) (__le32_to_cpu((sbp)->s_root_block))
|
||||
#define sb_journal_block(sbp) (__le32_to_cpu((sbp)->s_journal_block))
|
||||
#define set_sb_journal_block(sbp,v) ((sbp)->s_journal_block = __cpu_to_le32(v))
|
||||
#define sb_journal_size(sbp) (__le32_to_cpu((sbp)->s_journal_size))
|
||||
#define sb_blocksize(sbp) (__le16_to_cpu((sbp)->s_blocksize))
|
||||
#define set_sb_blocksize(sbp,v) ((sbp)->s_blocksize = __cpu_to_le16(v))
|
||||
#define sb_version(sbp) (__le16_to_cpu((sbp)->s_version))
|
||||
#define set_sb_version(sbp,v) ((sbp)->s_version = __cpu_to_le16(v))
|
||||
|
||||
|
||||
#define REISERFS_MAX_SUPPORTED_VERSION 2
|
||||
#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
|
||||
#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
|
||||
#define REISER3FS_SUPER_MAGIC_STRING "ReIsEr3Fs"
|
||||
|
||||
#define MAX_HEIGHT 7
|
||||
|
||||
/* must be correct to keep the desc and commit structs at 4k */
|
||||
#define JOURNAL_TRANS_HALF 1018
|
||||
|
||||
/* first block written in a commit. */
|
||||
struct reiserfs_journal_desc {
|
||||
__u32 j_trans_id; /* id of commit */
|
||||
__u32 j_len; /* length of commit. len +1 is the commit block */
|
||||
__u32 j_mount_id; /* mount id of this trans*/
|
||||
__u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the first blocks */
|
||||
char j_magic[12];
|
||||
};
|
||||
|
||||
/* last block written in a commit */
|
||||
struct reiserfs_journal_commit {
|
||||
__u32 j_trans_id; /* must match j_trans_id from the desc block */
|
||||
__u32 j_len; /* ditto */
|
||||
__u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the last blocks */
|
||||
char j_digest[16]; /* md5 sum of all the blocks involved, including desc and commit. not used, kill it */
|
||||
};
|
||||
|
||||
/* this header block gets written whenever a transaction is considered
|
||||
fully flushed, and is more recent than the last fully flushed
|
||||
transaction.
|
||||
fully flushed means all the log blocks and all the real blocks are
|
||||
on disk, and this transaction does not need to be replayed.
|
||||
*/
|
||||
struct reiserfs_journal_header {
|
||||
/* id of last fully flushed transaction */
|
||||
__u32 j_last_flush_trans_id;
|
||||
/* offset in the log of where to start replay after a crash */
|
||||
__u32 j_first_unflushed_offset;
|
||||
/* mount id to detect very old transactions */
|
||||
__u32 j_mount_id;
|
||||
};
|
||||
|
||||
/* magic string to find desc blocks in the journal */
|
||||
#define JOURNAL_DESC_MAGIC "ReIsErLB"
|
||||
|
||||
|
||||
/*
|
||||
* directories use this key as well as old files
|
||||
*/
|
||||
struct offset_v1
|
||||
{
|
||||
/*
|
||||
* for regular files this is the offset to the first byte of the
|
||||
* body, contained in the object-item, as measured from the start of
|
||||
* the entire body of the object.
|
||||
*
|
||||
* for directory entries, k_offset consists of hash derived from
|
||||
* hashing the name and using few bits (23 or more) of the resulting
|
||||
* hash, and generation number that allows distinguishing names with
|
||||
* hash collisions. If number of collisions overflows generation
|
||||
* number, we return EEXIST. High order bit is 0 always
|
||||
*/
|
||||
__u32 k_offset;
|
||||
__u32 k_uniqueness;
|
||||
};
|
||||
|
||||
struct offset_v2 {
|
||||
/*
|
||||
* for regular files this is the offset to the first byte of the
|
||||
* body, contained in the object-item, as measured from the start of
|
||||
* the entire body of the object.
|
||||
*
|
||||
* for directory entries, k_offset consists of hash derived from
|
||||
* hashing the name and using few bits (23 or more) of the resulting
|
||||
* hash, and generation number that allows distinguishing names with
|
||||
* hash collisions. If number of collisions overflows generation
|
||||
* number, we return EEXIST. High order bit is 0 always
|
||||
*/
|
||||
|
||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
/* little endian version */
|
||||
__u64 k_offset:60;
|
||||
__u64 k_type: 4;
|
||||
#elif defined(__BIG_ENDIAN_BITFIELD)
|
||||
/* big endian version */
|
||||
__u64 k_type: 4;
|
||||
__u64 k_offset:60;
|
||||
#else
|
||||
#error "__LITTLE_ENDIAN_BITFIELD or __BIG_ENDIAN_BITFIELD must be defined"
|
||||
#endif
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#define TYPE_MAXTYPE 3
|
||||
#define TYPE_ANY 15
|
||||
|
||||
#if (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
typedef union {
|
||||
struct offset_v2 offset_v2;
|
||||
__u64 linear;
|
||||
} __attribute__ ((__packed__)) offset_v2_esafe_overlay;
|
||||
|
||||
static inline __u16 offset_v2_k_type( const struct offset_v2 *v2 )
|
||||
{
|
||||
offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2;
|
||||
tmp.linear = __le64_to_cpu( tmp.linear );
|
||||
return (tmp.offset_v2.k_type <= TYPE_MAXTYPE)?tmp.offset_v2.k_type:TYPE_ANY;
|
||||
}
|
||||
|
||||
static inline loff_t offset_v2_k_offset( const struct offset_v2 *v2 )
|
||||
{
|
||||
offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2;
|
||||
tmp.linear = __le64_to_cpu( tmp.linear );
|
||||
return tmp.offset_v2.k_offset;
|
||||
}
|
||||
#elif (__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||
# define offset_v2_k_type(v2) ((v2)->k_type)
|
||||
# define offset_v2_k_offset(v2) ((v2)->k_offset)
|
||||
#else
|
||||
#error "__BYTE_ORDER must be __LITTLE_ENDIAN or __BIG_ENDIAN"
|
||||
#endif
|
||||
|
||||
struct key
|
||||
{
|
||||
/* packing locality: by default parent directory object id */
|
||||
__u32 k_dir_id;
|
||||
/* object identifier */
|
||||
__u32 k_objectid;
|
||||
/* the offset and node type (old and new form) */
|
||||
union
|
||||
{
|
||||
struct offset_v1 v1;
|
||||
struct offset_v2 v2;
|
||||
}
|
||||
u;
|
||||
};
|
||||
|
||||
#define KEY_SIZE (sizeof (struct key))
|
||||
|
||||
/* Header of a disk block. More precisely, header of a formatted leaf
|
||||
or internal node, and not the header of an unformatted node. */
|
||||
struct block_head
|
||||
{
|
||||
__u16 blk_level; /* Level of a block in the tree. */
|
||||
__u16 blk_nr_item; /* Number of keys/items in a block. */
|
||||
__u16 blk_free_space; /* Block free space in bytes. */
|
||||
struct key blk_right_delim_key; /* Right delimiting key for this block (supported for leaf level nodes
|
||||
only) */
|
||||
};
|
||||
#define BLKH_SIZE (sizeof (struct block_head))
|
||||
#define DISK_LEAF_NODE_LEVEL 1 /* Leaf node level. */
|
||||
|
||||
struct item_head
|
||||
{
|
||||
/* Everything in the tree is found by searching for it based on
|
||||
* its key.*/
|
||||
struct key ih_key;
|
||||
union {
|
||||
/* The free space in the last unformatted node of an
|
||||
indirect item if this is an indirect item. This
|
||||
equals 0xFFFF iff this is a direct item or stat data
|
||||
item. Note that the key, not this field, is used to
|
||||
determine the item type, and thus which field this
|
||||
union contains. */
|
||||
__u16 ih_free_space;
|
||||
/* Iff this is a directory item, this field equals the
|
||||
number of directory entries in the directory item. */
|
||||
__u16 ih_entry_count;
|
||||
} __attribute__ ((__packed__)) u;
|
||||
__u16 ih_item_len; /* total size of the item body */
|
||||
__u16 ih_item_location; /* an offset to the item body
|
||||
* within the block */
|
||||
__u16 ih_version; /* 0 for all old items, 2 for new
|
||||
ones. Highest bit is set by fsck
|
||||
temporary, cleaned after all
|
||||
done */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
/* size of item header */
|
||||
#define IH_SIZE (sizeof (struct item_head))
|
||||
|
||||
#define ITEM_VERSION_1 0
|
||||
#define ITEM_VERSION_2 1
|
||||
|
||||
#define ih_version(ih) (__le16_to_cpu((ih)->ih_version))
|
||||
|
||||
#define IH_KEY_OFFSET(ih) (ih_version(ih) == ITEM_VERSION_1 \
|
||||
? __le32_to_cpu((ih)->ih_key.u.v1.k_offset) \
|
||||
: offset_v2_k_offset(&((ih)->ih_key.u.v2)))
|
||||
|
||||
#define IH_KEY_ISTYPE(ih, type) (ih_version(ih) == ITEM_VERSION_1 \
|
||||
? __le32_to_cpu((ih)->ih_key.u.v1.k_uniqueness) == V1_##type \
|
||||
: offset_v2_k_type(&((ih)->ih_key.u.v2)) == V2_##type)
|
||||
|
||||
/***************************************************************************/
|
||||
/* DISK CHILD */
|
||||
/***************************************************************************/
|
||||
/* Disk child pointer: The pointer from an internal node of the tree
|
||||
to a node that is on disk. */
|
||||
struct disk_child {
|
||||
__u32 dc_block_number; /* Disk child's block number. */
|
||||
__u16 dc_size; /* Disk child's used space. */
|
||||
__u16 dc_reserved;
|
||||
};
|
||||
|
||||
#define DC_SIZE (sizeof(struct disk_child))
|
||||
#define dc_block_number(dc_p) (__le32_to_cpu((dc_p)->dc_block_number))
|
||||
|
||||
|
||||
/*
|
||||
* old stat data is 32 bytes long. We are going to distinguish new one by
|
||||
* different size
|
||||
*/
|
||||
struct stat_data_v1
|
||||
{
|
||||
__u16 sd_mode; /* file type, permissions */
|
||||
__u16 sd_nlink; /* number of hard links */
|
||||
__u16 sd_uid; /* owner */
|
||||
__u16 sd_gid; /* group */
|
||||
__u32 sd_size; /* file size */
|
||||
__u32 sd_atime; /* time of last access */
|
||||
__u32 sd_mtime; /* time file was last modified */
|
||||
__u32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */
|
||||
union {
|
||||
__u32 sd_rdev;
|
||||
__u32 sd_blocks; /* number of blocks file uses */
|
||||
} __attribute__ ((__packed__)) u;
|
||||
__u32 sd_first_direct_byte; /* first byte of file which is stored
|
||||
in a direct item: except that if it
|
||||
equals 1 it is a symlink and if it
|
||||
equals ~(__u32)0 there is no
|
||||
direct item. The existence of this
|
||||
field really grates on me. Let's
|
||||
replace it with a macro based on
|
||||
sd_size and our tail suppression
|
||||
policy. Someday. -Hans */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#define stat_data_v1(ih) (ih_version(ih) == ITEM_VERSION_1)
|
||||
#define sd_v1_mode(sdp) ((sdp)->sd_mode)
|
||||
#define sd_v1_nlink(sdp) (__le16_to_cpu((sdp)->sd_nlink))
|
||||
#define sd_v1_uid(sdp) (__le16_to_cpu((sdp)->sd_uid))
|
||||
#define sd_v1_gid(sdp) (__le16_to_cpu((sdp)->sd_gid))
|
||||
#define sd_v1_size(sdp) (__le32_to_cpu((sdp)->sd_size))
|
||||
#define sd_v1_mtime(sdp) (__le32_to_cpu((sdp)->sd_mtime))
|
||||
|
||||
/* Stat Data on disk (reiserfs version of UFS disk inode minus the
|
||||
address blocks) */
|
||||
struct stat_data {
|
||||
__u16 sd_mode; /* file type, permissions */
|
||||
__u16 sd_attrs; /* persistent inode flags */
|
||||
__u32 sd_nlink; /* number of hard links */
|
||||
__u64 sd_size; /* file size */
|
||||
__u32 sd_uid; /* owner */
|
||||
__u32 sd_gid; /* group */
|
||||
__u32 sd_atime; /* time of last access */
|
||||
__u32 sd_mtime; /* time file was last modified */
|
||||
__u32 sd_ctime; /* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */
|
||||
__u32 sd_blocks;
|
||||
union {
|
||||
__u32 sd_rdev;
|
||||
__u32 sd_generation;
|
||||
/*__u32 sd_first_direct_byte; */
|
||||
/* first byte of file which is stored in a
|
||||
direct item: except that if it equals 1
|
||||
it is a symlink and if it equals
|
||||
~(__u32)0 there is no direct item. The
|
||||
existence of this field really grates
|
||||
on me. Let's replace it with a macro
|
||||
based on sd_size and our tail
|
||||
suppression policy? */
|
||||
} __attribute__ ((__packed__)) u;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#define stat_data_v2(ih) (ih_version(ih) == ITEM_VERSION_2)
|
||||
#define sd_v2_mode(sdp) (__le16_to_cpu((sdp)->sd_mode))
|
||||
#define sd_v2_nlink(sdp) (__le32_to_cpu((sdp)->sd_nlink))
|
||||
#define sd_v2_size(sdp) (__le64_to_cpu((sdp)->sd_size))
|
||||
#define sd_v2_uid(sdp) (__le32_to_cpu((sdp)->sd_uid))
|
||||
#define sd_v2_gid(sdp) (__le32_to_cpu((sdp)->sd_gid))
|
||||
#define sd_v2_mtime(sdp) (__le32_to_cpu((sdp)->sd_mtime))
|
||||
|
||||
#define sd_mode(sdp) (__le16_to_cpu((sdp)->sd_mode))
|
||||
#define sd_size(sdp) (__le32_to_cpu((sdp)->sd_size))
|
||||
#define sd_size_hi(sdp) (__le32_to_cpu((sdp)->sd_size_hi))
|
||||
|
||||
struct reiserfs_de_head
|
||||
{
|
||||
__u32 deh_offset; /* third component of the directory entry key */
|
||||
__u32 deh_dir_id; /* objectid of the parent directory of the
|
||||
object, that is referenced by directory entry */
|
||||
__u32 deh_objectid;/* objectid of the object, that is referenced by
|
||||
directory entry */
|
||||
__u16 deh_location;/* offset of name in the whole item */
|
||||
__u16 deh_state; /* whether 1) entry contains stat data (for
|
||||
future), and 2) whether entry is hidden
|
||||
(unlinked) */
|
||||
};
|
||||
|
||||
#define DEH_SIZE (sizeof (struct reiserfs_de_head))
|
||||
#define deh_offset(p_deh) (__le32_to_cpu((p_deh)->deh_offset))
|
||||
#define deh_dir_id(p_deh) (__le32_to_cpu((p_deh)->deh_dir_id))
|
||||
#define deh_objectid(p_deh) (__le32_to_cpu((p_deh)->deh_objectid))
|
||||
#define deh_location(p_deh) (__le16_to_cpu((p_deh)->deh_location))
|
||||
#define deh_state(p_deh) (__le16_to_cpu((p_deh)->deh_state))
|
||||
|
||||
|
||||
#define DEH_Statdata (1 << 0) /* not used now */
|
||||
#define DEH_Visible (1 << 2)
|
||||
|
||||
#define SD_OFFSET 0
|
||||
#define SD_UNIQUENESS 0
|
||||
#define DOT_OFFSET 1
|
||||
#define DOT_DOT_OFFSET 2
|
||||
#define DIRENTRY_UNIQUENESS 500
|
||||
|
||||
#define V1_TYPE_STAT_DATA 0x0
|
||||
#define V1_TYPE_DIRECT 0xffffffff
|
||||
#define V1_TYPE_INDIRECT 0xfffffffe
|
||||
#define V1_TYPE_DIRECTORY_MAX 0xfffffffd
|
||||
#define V2_TYPE_STAT_DATA 0
|
||||
#define V2_TYPE_INDIRECT 1
|
||||
#define V2_TYPE_DIRECT 2
|
||||
#define V2_TYPE_DIRENTRY 3
|
||||
|
||||
#define REISERFS_ROOT_OBJECTID 2
|
||||
#define REISERFS_ROOT_PARENT_OBJECTID 1
|
||||
#define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024)
|
||||
/* the spot for the super in versions 3.5 - 3.5.11 (inclusive) */
|
||||
#define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024)
|
||||
#define REISERFS_OLD_BLOCKSIZE 4096
|
||||
|
||||
#define S_ISREG(mode) (((mode) & 0170000) == 0100000)
|
||||
#define S_ISDIR(mode) (((mode) & 0170000) == 0040000)
|
||||
#define S_ISLNK(mode) (((mode) & 0170000) == 0120000)
|
||||
|
||||
#define PATH_MAX 1024 /* include/linux/limits.h */
|
||||
#define MAX_LINK_COUNT 5 /* number of symbolic links to follow */
|
||||
|
||||
/* The size of the node cache */
|
||||
#define FSYSREISER_CACHE_SIZE 24*1024
|
||||
#define FSYSREISER_MIN_BLOCKSIZE SECTOR_SIZE
|
||||
#define FSYSREISER_MAX_BLOCKSIZE FSYSREISER_CACHE_SIZE / 3
|
||||
|
||||
/* Info about currently opened file */
|
||||
struct fsys_reiser_fileinfo
|
||||
{
|
||||
__u32 k_dir_id;
|
||||
__u32 k_objectid;
|
||||
};
|
||||
|
||||
/* In memory info about the currently mounted filesystem */
|
||||
struct fsys_reiser_info
|
||||
{
|
||||
/* The last read item head */
|
||||
struct item_head *current_ih;
|
||||
/* The last read item */
|
||||
char *current_item;
|
||||
/* The information for the currently opened file */
|
||||
struct fsys_reiser_fileinfo fileinfo;
|
||||
/* The start of the journal */
|
||||
__u32 journal_block;
|
||||
/* The size of the journal */
|
||||
__u32 journal_block_count;
|
||||
/* The first valid descriptor block in journal
|
||||
(relative to journal_block) */
|
||||
__u32 journal_first_desc;
|
||||
|
||||
/* The ReiserFS version. */
|
||||
__u16 version;
|
||||
/* The current depth of the reiser tree. */
|
||||
__u16 tree_depth;
|
||||
/* SECTOR_SIZE << blocksize_shift == blocksize. */
|
||||
__u8 blocksize_shift;
|
||||
/* 1 << full_blocksize_shift == blocksize. */
|
||||
__u8 fullblocksize_shift;
|
||||
/* The reiserfs block size (must be a power of 2) */
|
||||
__u16 blocksize;
|
||||
/* The number of cached tree nodes */
|
||||
__u16 cached_slots;
|
||||
/* The number of valid transactions in journal */
|
||||
__u16 journal_transactions;
|
||||
|
||||
unsigned int blocks[MAX_HEIGHT];
|
||||
unsigned int next_key_nr[MAX_HEIGHT];
|
||||
};
|
||||
|
||||
/* The cached s+tree blocks in FSYS_BUF, see below
|
||||
* for a more detailed description.
|
||||
*/
|
||||
#define ROOT ((char *) ((int) FSYS_BUF))
|
||||
#define CACHE(i) (ROOT + ((i) << INFO->fullblocksize_shift))
|
||||
#define LEAF CACHE (DISK_LEAF_NODE_LEVEL)
|
||||
|
||||
#define BLOCKHEAD(cache) ((struct block_head *) cache)
|
||||
#define ITEMHEAD ((struct item_head *) ((int) LEAF + BLKH_SIZE))
|
||||
#define KEY(cache) ((struct key *) ((int) cache + BLKH_SIZE))
|
||||
#define DC(cache) ((struct disk_child *) \
|
||||
((int) cache + BLKH_SIZE + KEY_SIZE * nr_item))
|
||||
/* The fsys_reiser_info block.
|
||||
*/
|
||||
#define INFO \
|
||||
((struct fsys_reiser_info *) ((int) FSYS_BUF + FSYSREISER_CACHE_SIZE))
|
||||
/*
|
||||
* The journal cache. For each transaction it contains the number of
|
||||
* blocks followed by the real block numbers of this transaction.
|
||||
*
|
||||
* If the block numbers of some transaction won't fit in this space,
|
||||
* this list is stopped with a 0xffffffff marker and the remaining
|
||||
* uncommitted transactions aren't cached.
|
||||
*/
|
||||
#define JOURNAL_START ((__u32 *) (INFO + 1))
|
||||
#define JOURNAL_END ((__u32 *) (FSYS_BUF + FSYS_BUFLEN))
|
||||
|
||||
|
||||
static __inline__ unsigned long
|
||||
log2 (unsigned long word)
|
||||
{
|
||||
#ifdef __I386__
|
||||
__asm__ ("bsfl %1,%0"
|
||||
: "=r" (word)
|
||||
: "r" (word));
|
||||
return word;
|
||||
#else
|
||||
int i;
|
||||
|
||||
for(i=0; i<(8*sizeof(word)); i++)
|
||||
if ((1<<i) & word)
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
is_power_of_two (unsigned long word)
|
||||
{
|
||||
return (word & -word) == word;
|
||||
}
|
||||
|
||||
extern const char *bb_mode_string(int mode);
|
||||
extern int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf);
|
|
@ -133,6 +133,8 @@ struct bootflow {
|
|||
* this uclass (used with things like "mmc")
|
||||
* @BOOTFLOWIF_SINGLE_MEDIA: (internal) Scan one media device in the uclass (used
|
||||
* with things like "mmc1")
|
||||
* @BOOTFLOWIF_SINGLE_PARTITION: (internal) Scan one partition in media device
|
||||
* (used with things like "mmc1:3")
|
||||
*/
|
||||
enum bootflow_iter_flags_t {
|
||||
BOOTFLOWIF_FIXED = 1 << 0,
|
||||
|
@ -148,6 +150,7 @@ enum bootflow_iter_flags_t {
|
|||
BOOTFLOWIF_SKIP_GLOBAL = 1 << 17,
|
||||
BOOTFLOWIF_SINGLE_UCLASS = 1 << 18,
|
||||
BOOTFLOWIF_SINGLE_MEDIA = 1 << 19,
|
||||
BOOTFLOWIF_SINGLE_PARTITION = 1 << 20,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
/*
|
||||
* Boot info
|
||||
*/
|
||||
#define SCB_PLAT_METADATA_OFFSET (0x510000)
|
||||
|
||||
/*
|
||||
* Hardware drivers support
|
||||
|
|
|
@ -688,4 +688,16 @@ static inline int log_get_default_format(void)
|
|||
(IS_ENABLED(CONFIG_LOGF_FUNC) ? BIT(LOGF_FUNC) : 0);
|
||||
}
|
||||
|
||||
struct global_data;
|
||||
/**
|
||||
* log_fixup_for_gd_move() - Handle global_data moving to a new place
|
||||
*
|
||||
* @new_gd: Pointer to the new global data
|
||||
*
|
||||
* The log_head list is part of global_data. Due to the way lists work, moving
|
||||
* the list will cause it to become invalid. This function fixes that up so
|
||||
* that the log_head list will work correctly.
|
||||
*/
|
||||
void log_fixup_for_gd_move(struct global_data *new_gd);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
|
||||
*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* (C) Copyright 2003 Sysgo Real-Time Solutions, AG <www.elinos.com>
|
||||
* Pavel Bartusek <pba@sysgo.de>
|
||||
*/
|
||||
|
||||
/* An implementation for the ReiserFS filesystem ported from GRUB.
|
||||
* Some parts of this code (mainly the structures and defines) are
|
||||
* from the original reiser fs code, as found in the linux kernel.
|
||||
*/
|
||||
|
||||
|
||||
#define SECTOR_SIZE 0x200
|
||||
#define SECTOR_BITS 9
|
||||
|
||||
struct blk_desc;
|
||||
struct disk_partition;
|
||||
|
||||
/* Error codes */
|
||||
typedef enum
|
||||
{
|
||||
ERR_NONE = 0,
|
||||
ERR_BAD_FILENAME,
|
||||
ERR_BAD_FILETYPE,
|
||||
ERR_BAD_GZIP_DATA,
|
||||
ERR_BAD_GZIP_HEADER,
|
||||
ERR_BAD_PART_TABLE,
|
||||
ERR_BAD_VERSION,
|
||||
ERR_BELOW_1MB,
|
||||
ERR_BOOT_COMMAND,
|
||||
ERR_BOOT_FAILURE,
|
||||
ERR_BOOT_FEATURES,
|
||||
ERR_DEV_FORMAT,
|
||||
ERR_DEV_VALUES,
|
||||
ERR_EXEC_FORMAT,
|
||||
ERR_FILELENGTH,
|
||||
ERR_FILE_NOT_FOUND,
|
||||
ERR_FSYS_CORRUPT,
|
||||
ERR_FSYS_MOUNT,
|
||||
ERR_GEOM,
|
||||
ERR_NEED_LX_KERNEL,
|
||||
ERR_NEED_MB_KERNEL,
|
||||
ERR_NO_DISK,
|
||||
ERR_NO_PART,
|
||||
ERR_NUMBER_PARSING,
|
||||
ERR_OUTSIDE_PART,
|
||||
ERR_READ,
|
||||
ERR_SYMLINK_LOOP,
|
||||
ERR_UNRECOGNIZED,
|
||||
ERR_WONT_FIT,
|
||||
ERR_WRITE,
|
||||
ERR_BAD_ARGUMENT,
|
||||
ERR_UNALIGNED,
|
||||
ERR_PRIVILEGED,
|
||||
ERR_DEV_NEED_INIT,
|
||||
ERR_NO_DISK_SPACE,
|
||||
ERR_NUMBER_OVERFLOW,
|
||||
|
||||
MAX_ERR_NUM
|
||||
} reiserfs_error_t;
|
||||
|
||||
|
||||
void reiserfs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info);
|
||||
extern int reiserfs_ls (char *dirname);
|
||||
extern int reiserfs_open (char *filename);
|
||||
extern int reiserfs_read (char *buf, unsigned len);
|
||||
extern int reiserfs_mount (unsigned part_length);
|
|
@ -6,6 +6,8 @@
|
|||
#if !defined _RNG_H_
|
||||
#define _RNG_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct udevice;
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,7 @@ if [ ${#dtc} -eq 0 ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if ! which $dtc >/dev/null ; then
|
||||
if ! which $dtc > /dev/null 2>&1 ; then
|
||||
echo "Error: Cannot find dtc: $dtc"
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
@ -544,7 +544,7 @@ static int prep_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev,
|
|||
"bootmeth_script", 0, ofnode_null(), &dev));
|
||||
|
||||
/* Enable the cros bootmeth if needed */
|
||||
if (bind_cros) {
|
||||
if (IS_ENABLED(CONFIG_BOOTMETH_CROS) && bind_cros) {
|
||||
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
|
||||
ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_cros),
|
||||
"cros", 0, ofnode_null(), &dev));
|
||||
|
|
|
@ -74,6 +74,9 @@ int bootstd_test_check_mmc_hunter(struct unit_test_state *uts)
|
|||
struct bootstd_priv *std;
|
||||
uint seq;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_MMC))
|
||||
return 0;
|
||||
|
||||
/* get access to the used hunters */
|
||||
ut_assertok(bootstd_get_priv(&std));
|
||||
|
||||
|
|
|
@ -240,7 +240,11 @@ static int mbr_test_run(struct unit_test_state *uts)
|
|||
ut_assert(ofnode_valid(node));
|
||||
ut_assertok(lists_bind_fdt(gd->dm_root, node, &dev, NULL, false));
|
||||
|
||||
mbr_parts_max = sizeof('\0') + 2 +
|
||||
/*
|
||||
* 1 byte for null character
|
||||
* 2 reserved bytes
|
||||
*/
|
||||
mbr_parts_max = 1 + 2 +
|
||||
strlen(mbr_parts_header) +
|
||||
strlen(mbr_parts_p1) +
|
||||
strlen(mbr_parts_p2) +
|
||||
|
|
|
@ -179,6 +179,16 @@ static int setexpr_test_regex(struct unit_test_state *uts)
|
|||
val = env_get("mary");
|
||||
ut_asserteq_str("this is a test", val);
|
||||
|
||||
/* No match */
|
||||
ut_assertok(run_command("setenv fred 'this is a test'", 0));
|
||||
ut_assertok(run_command("setenv mary ''", 0));
|
||||
ut_assertok(run_command("setexpr fred gsub us is \"${fred}\"", 0));
|
||||
ut_assertok(run_command("setexpr mary gsub us is \"${fred}\"", 0));
|
||||
val = env_get("fred");
|
||||
ut_asserteq_str("this is a test", val);
|
||||
val = env_get("mary");
|
||||
ut_asserteq_str("this is a test", val);
|
||||
|
||||
unmap_sysmem(buf);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -8,6 +8,7 @@ import pytest
|
|||
import u_boot_utils
|
||||
import uuid
|
||||
import datetime
|
||||
import re
|
||||
|
||||
"""
|
||||
Note: This test relies on boardenv_* containing configuration values to define
|
||||
|
@ -31,6 +32,12 @@ env__net_uses_pci = True
|
|||
# set to False.
|
||||
env__net_dhcp_server = True
|
||||
|
||||
# False or omitted if a DHCP server is attached to the network, and dhcp abort
|
||||
# case should be tested.
|
||||
# If DHCP abort testing is not possible or desired, set this variable to True.
|
||||
# For example: On some setup, dhcp is too fast and this case may not work.
|
||||
env__dhcp_abort_test_skip = True
|
||||
|
||||
# True if a DHCPv6 server is attached to the network, and should be tested.
|
||||
# If DHCPv6 testing is not possible or desired, this variable may be omitted or
|
||||
# set to False.
|
||||
|
@ -120,6 +127,57 @@ def test_net_dhcp(u_boot_console):
|
|||
global net_set_up
|
||||
net_set_up = True
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_dhcp')
|
||||
@pytest.mark.buildconfigspec('cmd_mii')
|
||||
def test_net_dhcp_abort(u_boot_console):
|
||||
"""Test the dhcp command by pressing ctrl+c in the middle of dhcp request
|
||||
|
||||
The boardenv_* file may be used to enable/disable this test; see the
|
||||
comment at the beginning of this file.
|
||||
"""
|
||||
|
||||
test_dhcp = u_boot_console.config.env.get('env__net_dhcp_server', False)
|
||||
if not test_dhcp:
|
||||
pytest.skip('No DHCP server available')
|
||||
|
||||
if u_boot_console.config.env.get('env__dhcp_abort_test_skip', True):
|
||||
pytest.skip('DHCP abort test is not enabled!')
|
||||
|
||||
u_boot_console.run_command('setenv autoload no')
|
||||
|
||||
# Phy reset before running dhcp command
|
||||
output = u_boot_console.run_command('mii device')
|
||||
if not re.search(r"Current device: '(.+?)'", output):
|
||||
pytest.skip('PHY device does not exist!')
|
||||
eth_num = re.search(r"Current device: '(.+?)'", output).groups()[0]
|
||||
u_boot_console.run_command(f'mii device {eth_num}')
|
||||
output = u_boot_console.run_command('mii info')
|
||||
eth_addr = hex(int(re.search(r'PHY (.+?):', output).groups()[0], 16))
|
||||
u_boot_console.run_command(f'mii modify {eth_addr} 0 0x8000 0x8000')
|
||||
|
||||
u_boot_console.run_command('dhcp', wait_for_prompt=False)
|
||||
try:
|
||||
u_boot_console.wait_for('Waiting for PHY auto negotiation to complete')
|
||||
except:
|
||||
pytest.skip('Timeout waiting for PHY auto negotiation to complete')
|
||||
|
||||
u_boot_console.wait_for('done')
|
||||
|
||||
try:
|
||||
# Sending Ctrl-C
|
||||
output = u_boot_console.run_command(
|
||||
chr(3), wait_for_echo=False, send_nl=False
|
||||
)
|
||||
assert 'TIMEOUT' not in output
|
||||
assert 'DHCP client bound to address ' not in output
|
||||
assert 'Abort' in output
|
||||
finally:
|
||||
# Provide a time to recover from Abort - if it is not performed
|
||||
# There is message like: ethernet@ff0e0000: No link.
|
||||
u_boot_console.run_command('sleep 1')
|
||||
# Run the dhcp test to setup the network configuration
|
||||
test_net_dhcp(u_boot_console)
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_dhcp6')
|
||||
def test_net_dhcp6(u_boot_console):
|
||||
"""Test the dhcp6 command.
|
||||
|
|
Loading…
Add table
Reference in a new issue