Compare commits
60 commits
Author | SHA1 | Date | |
---|---|---|---|
f6a0df91fb | |||
6218392785 | |||
a59ae21e47 | |||
14777d1f0c | |||
8e16dc9e6a | |||
e6d95a3a60 | |||
5920196f4f | |||
6e5b3caccb | |||
f1a2bace41 | |||
79dcff6403 | |||
7a92ed1473 | |||
07c7d73a57 | |||
a977573540 | |||
4964bf1692 | |||
7d66d2ca4d | |||
757ba49d65 | |||
dccc4a2c35 | |||
4f3bbdaeca | |||
4ea1f591bc | |||
a95fcbdb0b | |||
bece952194 | |||
65b22fab10 | |||
0cf1cf36b8 | |||
bbe240e612 | |||
ce01289423 | |||
eb0287f9c0 | |||
6a1f04ae97 | |||
3a002c5a64 | |||
3e183c4b98 | |||
dc4fd98195 | |||
87a35b80a6 | |||
39105d4fa7 | |||
e2ed1ccd08 | |||
ebffb583a3 | |||
33327a5708 | |||
9f5d708f1a | |||
e0cc11fd56 | |||
dec99e46ed | |||
8e01e9917f | |||
0579c5474a | |||
735b1307eb | |||
0e16eff1db | |||
0650514998 | |||
3fa14acfdd | |||
1ba6bb964b | |||
75542063f3 | |||
f1c48e949e | |||
6906045816 | |||
ae0a500435 | |||
6a4c0e0913 | |||
4c5a5bf78c | |||
842b0f524f | |||
49425949b0 | |||
4555a9c05b | |||
ee7b43ab91 | |||
f32f7cee7e | |||
3caedab939 | |||
1cf7ff1e98 | |||
c7bc267ff0 | |||
154322b7d8 |
|
@ -1,29 +0,0 @@
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
kernel:
|
|
||||||
runs-on: local/aarch64-linux
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: set home
|
|
||||||
run: |
|
|
||||||
echo "HOME=$PWD" >> "$GITHUB_ENV"
|
|
||||||
|
|
||||||
- name: build all
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
TARGETS=$(nix eval .#packages.aarch64-linux --apply 'builtins.attrNames' --json | jq '. | map(".#" + .) | join(" ")' -r)
|
|
||||||
OUTPUT=$(nix build --print-out-paths --keep-going $TARGETS)
|
|
||||||
echo $OUTPUT
|
|
||||||
echo "$OUTPUT" > build.out
|
|
||||||
|
|
||||||
- name: upload to cachix
|
|
||||||
run: |
|
|
||||||
cachix push nixos-x13s $(cat build.out)
|
|
||||||
env:
|
|
||||||
CACHIX_AUTH_TOKEN: '${{ secrets.CACHIX_TOKEN_X13S }}'
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
.secret.envrc
|
.secret.envrc
|
||||||
|
result
|
||||||
|
|
25
.woodpecker/build.yaml
Normal file
25
.woodpecker/build.yaml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
labels:
|
||||||
|
type: local
|
||||||
|
system: aarch64-linux
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: find-targets
|
||||||
|
image: bash
|
||||||
|
commands:
|
||||||
|
- nix develop .#ci -c just -- find-targets
|
||||||
|
|
||||||
|
- name: build
|
||||||
|
image: bash
|
||||||
|
commands:
|
||||||
|
- tini -s nix -- develop .#ci -c just -- build
|
||||||
|
|
||||||
|
- name: upload
|
||||||
|
image: bash
|
||||||
|
commands:
|
||||||
|
- nix develop .#ci -c just -- push
|
||||||
|
environment:
|
||||||
|
CACHIX_AUTH_TOKEN:
|
||||||
|
from_secret: CACHIX_AUTH_TOKEN
|
||||||
|
|
||||||
|
when:
|
||||||
|
- event: push
|
49
README.md
49
README.md
|
@ -1,5 +1,8 @@
|
||||||
# nixos x13s
|
# nixos x13s
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> This project is unmaintained.
|
||||||
|
|
||||||
This repository aims to provide easy, shared, support for Lenovo X13s on Linux.
|
This repository aims to provide easy, shared, support for Lenovo X13s on Linux.
|
||||||
|
|
||||||
The support for this machine is constantly improving in mainline kernel and upstream packages. Eventually the goal is that this repository is no longer necessary.
|
The support for this machine is constantly improving in mainline kernel and upstream packages. Eventually the goal is that this repository is no longer necessary.
|
||||||
|
@ -12,6 +15,19 @@ https://app.cachix.org/cache/nixos-x13s
|
||||||
|
|
||||||
Ensure you are not overriding the nixpkgs input when consuming this flake, or you may not be able to take advantages of this cache.
|
Ensure you are not overriding the nixpkgs input when consuming this flake, or you may not be able to take advantages of this cache.
|
||||||
|
|
||||||
|
NixOS configuration example:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
nix.settings = {
|
||||||
|
substituters = [
|
||||||
|
"https://nixos-x13s.cachix.org"
|
||||||
|
];
|
||||||
|
trusted-public-keys = [
|
||||||
|
"nixos-x13s.cachix.org-1:SzroHbidolBD3Sf6UusXp12YZ+a5ynWv0RtYF0btFos="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## Add with a flake
|
## Add with a flake
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
|
@ -30,12 +46,12 @@ Ensure you are not overriding the nixpkgs input when consuming this flake, or yo
|
||||||
inputs.nixos-x13s.nixosModules.default
|
inputs.nixos-x13s.nixosModules.default
|
||||||
{
|
{
|
||||||
nixos-x13s.enable = true;
|
nixos-x13s.enable = true;
|
||||||
nixos-x13s.kernel = "jhovold"; # jhovold is default, but steev and mainline supported
|
nixos-x13s.kernel = "jhovold"; # jhovold is default, but mainline supported
|
||||||
|
|
||||||
# install multiple kernels! note this increases eval time for each specialization
|
# install multiple kernels! note this increases eval time for each specialization
|
||||||
specialisation = {
|
specialisation = {
|
||||||
|
# note that activation of each specialization is required to copy the dtb to the EFI, and thus boot
|
||||||
mainline.configuration.nixos-x13s.kernel = "mainline";
|
mainline.configuration.nixos-x13s.kernel = "mainline";
|
||||||
steev.configuration.nixos-x13s.kernel = "steev";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# allow unfree firmware
|
# allow unfree firmware
|
||||||
|
@ -52,4 +68,31 @@ Ensure you are not overriding the nixpkgs input when consuming this flake, or yo
|
||||||
|
|
||||||
## Add using not a flake
|
## Add using not a flake
|
||||||
|
|
||||||
Not documented, but feel free to submit a PR.
|
Clone the repository:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://codeberg.org/adamcstephens/nixos-x13s /etc/nixos/nixos-x13s
|
||||||
|
```
|
||||||
|
|
||||||
|
Then reference the module in your `configuration.nix` and use the module as documented in the flake example above:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
imports =
|
||||||
|
[
|
||||||
|
./nixos-x13s/module.nix
|
||||||
|
];
|
||||||
|
nixos-x13s.enable = true;
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## UEFI Update ISO
|
||||||
|
|
||||||
|
This repository provides a package which can output the USB UEFI Update ISO. This will be updated as Lenovo releases new versions.
|
||||||
|
|
||||||
|
```
|
||||||
|
nix build .#uefi-usbiso
|
||||||
|
|
||||||
|
dd if=result/usbdisk-*.iso of=/path/to/usb/disk
|
||||||
|
```
|
||||||
|
|
||||||
|
Reboot, select USB drive from F12 boot menu, follow wizard.
|
||||||
|
|
30
flake.lock
30
flake.lock
|
@ -5,11 +5,11 @@
|
||||||
"nixpkgs-lib": "nixpkgs-lib"
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1706830856,
|
"lastModified": 1719994518,
|
||||||
"narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=",
|
"narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f",
|
"rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -20,11 +20,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1707689078,
|
"lastModified": 1722062969,
|
||||||
"narHash": "sha256-UUGmRa84ZJHpGZ1WZEBEUOzaPOWG8LZ0yPg1pdDF/yM=",
|
"narHash": "sha256-QOS0ykELUmPbrrUGmegAUlpmUFznDQeR4q7rFhl8eQg=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "f9d39fb9aff0efee4a3d5f4a6d7c17701d38a1d8",
|
"rev": "b73c2221a46c13557b1b3be9c2070cc42cf01eb3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -36,20 +36,14 @@
|
||||||
},
|
},
|
||||||
"nixpkgs-lib": {
|
"nixpkgs-lib": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "lib",
|
"lastModified": 1719876945,
|
||||||
"lastModified": 1706550542,
|
"narHash": "sha256-Fm2rDDs86sHy0/1jxTOKB1118Q0O3Uc7EC0iXvXKpbI=",
|
||||||
"narHash": "sha256-UcsnCG6wx++23yeER4Hg18CXWbgNpqNXcHIo5/1Y+hc=",
|
"type": "tarball",
|
||||||
"owner": "NixOS",
|
"url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz"
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "97b17f32362e475016f942bbdfda4a4a72a8a652",
|
|
||||||
"type": "github"
|
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"dir": "lib",
|
"type": "tarball",
|
||||||
"owner": "NixOS",
|
"url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz"
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
|
|
106
flake.nix
106
flake.nix
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
inputs@{ flake-parts, self, ... }:
|
inputs@{ flake-parts, self, ... }:
|
||||||
|
let
|
||||||
|
dtbName = "sc8280xp-lenovo-thinkpad-x13s.dtb";
|
||||||
|
in
|
||||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||||
imports = [ ./packages/part.nix ];
|
imports = [ ./packages/part.nix ];
|
||||||
|
|
||||||
|
@ -17,24 +20,36 @@
|
||||||
perSystem =
|
perSystem =
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
devShells.default = pkgs.mkShellNoCC { packages = [ pkgs.npins ]; };
|
devShells = rec {
|
||||||
|
default = pkgs.mkShellNoCC { packages = [ pkgs.npins ] ++ ci.nativeBuildInputs; };
|
||||||
|
|
||||||
|
ci = pkgs.mkShellNoCC {
|
||||||
|
packages = [
|
||||||
|
pkgs.cachix
|
||||||
|
pkgs.jq
|
||||||
|
pkgs.just
|
||||||
|
(pkgs.python3.withPackages (py: [
|
||||||
|
py.PyGithub
|
||||||
|
py.packaging
|
||||||
|
]))
|
||||||
|
pkgs.pyright
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.nixosModules.default = import ./module.nix;
|
flake.nixosModules.default = import ./module.nix { inherit dtbName; };
|
||||||
|
|
||||||
flake.nixosConfigurations.example = inputs.nixpkgs.lib.nixosSystem {
|
flake.nixosConfigurations = {
|
||||||
|
example = inputs.nixpkgs.lib.nixosSystem {
|
||||||
system = "aarch64-linux";
|
system = "aarch64-linux";
|
||||||
modules = [
|
modules = [
|
||||||
self.nixosModules.default
|
self.nixosModules.default
|
||||||
|
(
|
||||||
|
{ config, pkgs, ... }:
|
||||||
{
|
{
|
||||||
nixos-x13s.enable = true;
|
nixos-x13s.enable = true;
|
||||||
nixos-x13s.kernel = "jhovold"; # jhovold is default, but steev and mainline supported
|
nixos-x13s.kernel = "jhovold"; # jhovold is default, but mainline supported
|
||||||
|
|
||||||
# install multiple kernels! note this increases eval time for each specialization
|
|
||||||
specialisation = {
|
|
||||||
mainline.configuration.nixos-x13s.kernel = "mainline";
|
|
||||||
steev.configuration.nixos-x13s.kernel = "steev";
|
|
||||||
};
|
|
||||||
|
|
||||||
# allow unfree firmware
|
# allow unfree firmware
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
@ -42,7 +57,78 @@
|
||||||
# define your fileSystems
|
# define your fileSystems
|
||||||
fileSystems."/".device = "/dev/notreal";
|
fileSystems."/".device = "/dev/notreal";
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
iso = inputs.nixpkgs.lib.nixosSystem {
|
||||||
|
system = "aarch64-linux";
|
||||||
|
modules = [
|
||||||
|
|
||||||
|
self.nixosModules.default
|
||||||
|
(
|
||||||
|
{
|
||||||
|
modulesPath,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
image = import "${inputs.nixpkgs}/nixos/lib/make-disk-image.nix" {
|
||||||
|
inherit config lib pkgs;
|
||||||
|
|
||||||
|
name = "nixos-x13s-bootstrap";
|
||||||
|
diskSize = "auto";
|
||||||
|
format = "raw";
|
||||||
|
partitionTableType = "efi";
|
||||||
|
copyChannel = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
hardware.deviceTree = {
|
||||||
|
enable = true;
|
||||||
|
name = "qcom/${dtbName}";
|
||||||
|
};
|
||||||
|
|
||||||
|
system.build.bootstrap-image = image;
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
initrd = {
|
||||||
|
systemd.enable = true;
|
||||||
|
systemd.emergencyAccess = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
loader = {
|
||||||
|
grub.enable = false;
|
||||||
|
systemd-boot.enable = true;
|
||||||
|
systemd-boot.graceful = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
|
nixos-x13s = {
|
||||||
|
enable = true;
|
||||||
|
bluetoothMac = "02:68:b3:29:da:98";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems = {
|
||||||
|
"/boot" = {
|
||||||
|
fsType = "vfat";
|
||||||
|
device = "/dev/disk/by-label/ESP";
|
||||||
|
};
|
||||||
|
"/" = {
|
||||||
|
device = "/dev/disk/by-label/nixos";
|
||||||
|
fsType = "ext4";
|
||||||
|
autoResize = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
12
justfile
Normal file
12
justfile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
all:
|
||||||
|
just -l
|
||||||
|
|
||||||
|
find-targets:
|
||||||
|
nix eval .#packages.aarch64-linux --apply 'builtins.attrNames' --json | jq '. | map(".#" + .) | join(" ")' -r > targets
|
||||||
|
|
||||||
|
build:
|
||||||
|
nix build --print-out-paths --keep-going $(cat targets) > outputs
|
||||||
|
cat outputs
|
||||||
|
|
||||||
|
push:
|
||||||
|
cachix -- push nixos-x13s $(cat outputs)
|
97
module.nix
97
module.nix
|
@ -1,6 +1,8 @@
|
||||||
|
{ dtbName }:
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
|
options,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
@ -9,23 +11,30 @@ let
|
||||||
|
|
||||||
x13sPackages = import ./packages/default.nix { inherit lib pkgs; };
|
x13sPackages = import ./packages/default.nix { inherit lib pkgs; };
|
||||||
|
|
||||||
dtbName = "sc8280xp-lenovo-thinkpad-x13s.dtb";
|
|
||||||
linuxPackages_x13s =
|
linuxPackages_x13s =
|
||||||
if cfg.kernel == "mainline" then
|
if cfg.kernel == "mainline" then
|
||||||
pkgs.linuxPackages_latest
|
pkgs.linuxPackages_latest
|
||||||
else
|
else
|
||||||
pkgs.linuxPackagesFor (
|
pkgs.linuxPackagesFor (
|
||||||
if cfg.kernel == "jhovold" then
|
if cfg.kernel == "jhovold" then x13sPackages.linux_jhovold else throw "Unsupported kernel"
|
||||||
x13sPackages.linux_jhovold
|
|
||||||
else if cfg.kernel == "jhovold_6_7" then
|
|
||||||
x13sPackages.linux_jhovold_6_7
|
|
||||||
else if cfg.kernel == "steev" then
|
|
||||||
x13sPackages.linux_steev
|
|
||||||
else
|
|
||||||
throw "Unsupported kernel"
|
|
||||||
);
|
);
|
||||||
dtb = "${linuxPackages_x13s.kernel}/dtbs/qcom/${dtbName}";
|
dtb = "${linuxPackages_x13s.kernel}/dtbs/qcom/${dtbName}";
|
||||||
dtbEfiPath = "dtbs/${cfg.kernel}/${config.boot.kernelPackages.kernel.version}/${dtbName}";
|
dtbEfiPath = "dtbs/x13s.dtb";
|
||||||
|
|
||||||
|
modulesClosure = pkgs.makeModulesClosure {
|
||||||
|
rootModules = config.boot.initrd.availableKernelModules ++ config.boot.initrd.kernelModules;
|
||||||
|
kernel = config.system.modulesTree;
|
||||||
|
firmware = config.hardware.firmware;
|
||||||
|
allowMissing = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
modulesWithExtra = pkgs.symlinkJoin {
|
||||||
|
name = "modules-closure";
|
||||||
|
paths = [
|
||||||
|
modulesClosure
|
||||||
|
x13sPackages.graphics-firmware
|
||||||
|
];
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.nixos-x13s = {
|
options.nixos-x13s = {
|
||||||
|
@ -33,37 +42,38 @@ in
|
||||||
|
|
||||||
bluetoothMac = lib.mkOption {
|
bluetoothMac = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
description = "mac address to set on boot";
|
description = "Bluetooth MAC address to set on boot";
|
||||||
};
|
};
|
||||||
|
|
||||||
kernel = lib.mkOption {
|
kernel = lib.mkOption {
|
||||||
type = lib.types.enum [
|
type = lib.types.enum [
|
||||||
"jhovold"
|
"jhovold"
|
||||||
"jhovold_6_7"
|
|
||||||
"mainline"
|
"mainline"
|
||||||
"steev"
|
|
||||||
];
|
];
|
||||||
description = "which patched kernel to use. jhovold is the latest RC, steev is the latest patched release, and mainline is nixos latest";
|
description = "Which patched kernel to use. jhovold is the latest RC or release with some x13s specific patches, and mainline is nixos latest";
|
||||||
default = "jhovold";
|
default = "jhovold";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = false;
|
||||||
|
message = "adamcstephens/nixos-x13s is no longer maintained";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.efibootmgr ];
|
environment.systemPackages = [ pkgs.efibootmgr ];
|
||||||
|
|
||||||
hardware.enableAllFirmware = true;
|
hardware.enableAllFirmware = true;
|
||||||
hardware.firmware = [ x13sPackages."x13s/extra-firmware" ];
|
hardware.firmware = lib.mkBefore [ x13sPackages.graphics-firmware ];
|
||||||
|
|
||||||
systemd.services.pd-mapper = {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${lib.getExe x13sPackages.pd-mapper}";
|
|
||||||
Restart = "always";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
|
initrd.systemd.enable = true;
|
||||||
|
initrd.systemd.contents = {
|
||||||
|
"/lib".source = lib.mkForce "${modulesWithExtra}/lib";
|
||||||
|
};
|
||||||
|
|
||||||
loader.efi.canTouchEfiVariables = true;
|
loader.efi.canTouchEfiVariables = true;
|
||||||
loader.systemd-boot.enable = lib.mkDefault true;
|
loader.systemd-boot.enable = lib.mkDefault true;
|
||||||
loader.systemd-boot.extraFiles = {
|
loader.systemd-boot.extraFiles = {
|
||||||
|
@ -80,11 +90,8 @@ in
|
||||||
"efi=noruntime"
|
"efi=noruntime"
|
||||||
"clk_ignore_unused"
|
"clk_ignore_unused"
|
||||||
"pd_ignore_unused"
|
"pd_ignore_unused"
|
||||||
"regulator_ignore_unused"
|
|
||||||
"arm64.nopauth"
|
"arm64.nopauth"
|
||||||
|
# "regulator_ignore_unused" # allows for > 30 sec to load msm, at the potential cost of power
|
||||||
# blacklist graphics in initrd so the firmware can load from disk
|
|
||||||
"rd.driver.blacklist=msm"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
initrd = {
|
initrd = {
|
||||||
|
@ -108,11 +115,19 @@ in
|
||||||
"dispcc_sc8280xp"
|
"dispcc_sc8280xp"
|
||||||
"phy_qcom_edp"
|
"phy_qcom_edp"
|
||||||
"panel-edp"
|
"panel-edp"
|
||||||
# "msm"
|
"msm"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# https://github.com/jhovold/linux/wiki/X13s#modem
|
||||||
|
networking.networkmanager.fccUnlockScripts = [
|
||||||
|
{
|
||||||
|
id = "105b:e0c3";
|
||||||
|
path = "${pkgs.modemmanager}/share/ModemManager/fcc-unlock.available.d/105b";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
nixpkgs.overlays = [
|
nixpkgs.overlays = [
|
||||||
(_: super: {
|
(_: super: {
|
||||||
# don't try and use zfs
|
# don't try and use zfs
|
||||||
|
@ -128,17 +143,21 @@ in
|
||||||
# default is performance
|
# default is performance
|
||||||
powerManagement.cpuFreqGovernor = "ondemand";
|
powerManagement.cpuFreqGovernor = "ondemand";
|
||||||
|
|
||||||
systemd.services.bluetooth = {
|
# https://github.com/jhovold/linux/wiki/X13s#camera
|
||||||
|
services.udev.extraRules = ''
|
||||||
|
ACTION=="add", SUBSYSTEM=="dma_heap", KERNEL=="linux,cma", GROUP="video", MODE="0660"
|
||||||
|
ACTION=="add", SUBSYSTEM=="dma_heap", KERNEL=="system", GROUP="video", MODE="0660"
|
||||||
|
'';
|
||||||
|
|
||||||
|
systemd.services.bluetooth-x13s-mac = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
before = [ "bluetooth.service" ];
|
||||||
|
requiredBy = [ "bluetooth.service" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
# disabled because btmgmt call hangs
|
Type = "oneshot";
|
||||||
# ExecStartPre = [
|
RemainAfterExit = true;
|
||||||
# ""
|
ExecStart = "${pkgs.util-linux}/bin/script -q -c '${pkgs.bluez}/bin/btmgmt --index 0 public-addr ${cfg.bluetoothMac}'";
|
||||||
# "${pkgs.util-linux}/bin/rfkill block bluetooth"
|
|
||||||
# "${pkgs.bluez5-experimental}/bin/btmgmt public-addr ${cfg.bluetoothMac}"
|
|
||||||
# "${pkgs.util-linux}/bin/rfkill unblock bluetooth"
|
|
||||||
# ];
|
|
||||||
RestartSec = 5;
|
|
||||||
Restart = "on-failure";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,19 +1,5 @@
|
||||||
{
|
{
|
||||||
"pins": {
|
"pins": {
|
||||||
"alsa-ucm-conf": {
|
|
||||||
"type": "GitRelease",
|
|
||||||
"repository": {
|
|
||||||
"type": "GitHub",
|
|
||||||
"owner": "alsa-project",
|
|
||||||
"repo": "alsa-ucm-conf"
|
|
||||||
},
|
|
||||||
"pre_releases": false,
|
|
||||||
"version_upper_bound": null,
|
|
||||||
"version": "v1.2.11",
|
|
||||||
"revision": "c40b8cc795c8fe4c83582857d5e317f18a4c065e",
|
|
||||||
"url": "https://api.github.com/repos/alsa-project/alsa-ucm-conf/tarball/v1.2.11",
|
|
||||||
"hash": "1jcn0x6bbg69p1ygxnh1zn33sd9lpbll4bnhvkzw1fjpmw7igjkz"
|
|
||||||
},
|
|
||||||
"linux-jhovold": {
|
"linux-jhovold": {
|
||||||
"type": "Git",
|
"type": "Git",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -21,34 +7,10 @@
|
||||||
"owner": "jhovold",
|
"owner": "jhovold",
|
||||||
"repo": "linux"
|
"repo": "linux"
|
||||||
},
|
},
|
||||||
"branch": "wip/sc8280xp-v6.8",
|
"branch": "wip/sc8280xp-6.11-rc1",
|
||||||
"revision": "935f2e13e13d2dcfb923d3b0881c905861a7a9ce",
|
"revision": "9c6b81022b9c277d65c68e25f4cfd52f33ef8f28",
|
||||||
"url": "https://github.com/jhovold/linux/archive/935f2e13e13d2dcfb923d3b0881c905861a7a9ce.tar.gz",
|
"url": "https://github.com/jhovold/linux/archive/9c6b81022b9c277d65c68e25f4cfd52f33ef8f28.tar.gz",
|
||||||
"hash": "031lssdf455v82qxaj7rhs9z809i16is03xwc6354p5xafrqj3cj"
|
"hash": "13c6r67iy8y750f8zpals4l941lshxx3w3ar1ss9dizsqjsghdsr"
|
||||||
},
|
|
||||||
"linux-jhovold-6_7": {
|
|
||||||
"type": "Git",
|
|
||||||
"repository": {
|
|
||||||
"type": "GitHub",
|
|
||||||
"owner": "jhovold",
|
|
||||||
"repo": "linux"
|
|
||||||
},
|
|
||||||
"branch": "wip/sc8280xp-v6.7",
|
|
||||||
"revision": "b929f8eed9ad1f156cae932dea741bc4383e6367",
|
|
||||||
"url": "https://github.com/jhovold/linux/archive/b929f8eed9ad1f156cae932dea741bc4383e6367.tar.gz",
|
|
||||||
"hash": "12j92hns95rviajyxpj57hgdr1k9lrd6rzxng87m4v4m7pi8v51l"
|
|
||||||
},
|
|
||||||
"linux-steev": {
|
|
||||||
"type": "Git",
|
|
||||||
"repository": {
|
|
||||||
"type": "GitHub",
|
|
||||||
"owner": "steev",
|
|
||||||
"repo": "linux"
|
|
||||||
},
|
|
||||||
"branch": "lenovo-x13s-linux-6.7.y",
|
|
||||||
"revision": "5e9c982da90e7546586b56ff92e785c8d9edd14b",
|
|
||||||
"url": "https://github.com/steev/linux/archive/5e9c982da90e7546586b56ff92e785c8d9edd14b.tar.gz",
|
|
||||||
"hash": "1ig1rrgq93gwv7jj21hwdcpkdw0v4ba3v2k3j3jj5z6r97z6xcag"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version": 3
|
"version": 3
|
||||||
|
|
|
@ -14,63 +14,23 @@ let
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
in
|
in
|
||||||
rec {
|
{
|
||||||
linux_jhovold = linux_jhovold_6_8;
|
linux_jhovold = pkgs.callPackage linux_x13s_pkg {
|
||||||
|
|
||||||
linux_jhovold_6_8 = pkgs.callPackage linux_x13s_pkg {
|
|
||||||
src = sources.linux-jhovold;
|
src = sources.linux-jhovold;
|
||||||
version = "6.8.0";
|
version = "6.11.0-rc1";
|
||||||
defconfig = "johan_defconfig";
|
defconfig = "johan_defconfig";
|
||||||
};
|
};
|
||||||
|
|
||||||
linux_jhovold_6_7 = pkgs.callPackage linux_x13s_pkg {
|
graphics-firmware =
|
||||||
src = sources.linux-jhovold-6_7;
|
let
|
||||||
version = "6.7.0";
|
gpu-src = pkgs.fetchurl {
|
||||||
defconfig = "johan_defconfig";
|
url = "https://download.lenovo.com/pccbbs/mobiles/n3hdr20w.exe";
|
||||||
|
hash = "sha256-Jwyl9uKOnjpwfHd+VaGHjYs9x8cUuRdFCERuXqaJwEY=";
|
||||||
};
|
};
|
||||||
|
in
|
||||||
linux_steev = pkgs.callPackage linux_x13s_pkg {
|
pkgs.runCommand "graphics-firmware" { } ''
|
||||||
src = sources.linux-steev;
|
mkdir -vp "$out/lib/firmware/qcom/sc8280xp/LENOVO/21BX"
|
||||||
version = "6.7.7";
|
${lib.getExe pkgs.innoextract} ${gpu-src}
|
||||||
defconfig = "laptop_defconfig";
|
cp -v code\$GetExtractPath\$/*/*.mbn "$out/lib/firmware/qcom/sc8280xp/LENOVO/21BX/"
|
||||||
|
'';
|
||||||
# fix build using extra config from
|
|
||||||
# https://github.com/boletus-edulis/hydra-test/blob/fffbd42c511e7384be76dc88ea246bc7064d7b49/pkgs/linux_x13s.nix
|
|
||||||
structuredExtraConfig = with lib.kernel; {
|
|
||||||
VIDEO_AR1337 = no;
|
|
||||||
AUDIT = yes;
|
|
||||||
ARM64_SME = yes;
|
|
||||||
MAC80211_LEDS = yes;
|
|
||||||
FW_LOADER_USER_HELPER = yes;
|
|
||||||
QCOM_EBI2 = yes;
|
|
||||||
EFI_CAPSULE_LOADER = yes;
|
|
||||||
SRAM = yes;
|
|
||||||
KEYBOARD_GPIO = yes;
|
|
||||||
SERIAL_QCOM_GENI = yes;
|
|
||||||
PINCTRL_QCOM_SPMI_PMIC = yes;
|
|
||||||
PINCTRL_SC8280XP_LPASS_LPI = module;
|
|
||||||
QCOM_TSENS = yes;
|
|
||||||
BACKLIGHT_CLASS_DEVICE = yes;
|
|
||||||
VIRTIO_MENU = yes;
|
|
||||||
VHOST_MENU = yes;
|
|
||||||
SC_GCC_8280XP = yes;
|
|
||||||
SC_GPUCC_8280XP = yes;
|
|
||||||
QCOM_Q6V5_ADSP = module;
|
|
||||||
QCOM_STATS = yes;
|
|
||||||
QCOM_CPR = yes;
|
|
||||||
QCOM_RPMHPD = yes;
|
|
||||||
QCOM_RPMPD = yes;
|
|
||||||
PHY_QCOM_QMP_PCIE_8996 = yes;
|
|
||||||
NVMEM_QCOM_QFPROM = yes;
|
|
||||||
CRYPTO_AES_ARM64_CE_BLK = yes;
|
|
||||||
CRYPTO_AES_ARM64_BS = yes;
|
|
||||||
CRYPTO_AES_ARM64_CE_CCM = yes;
|
|
||||||
CONFIG_CRYPTO_DEV_CCREE = module;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
pd-mapper = pkgs.callPackage ./pd-mapper { inherit qrtr; };
|
|
||||||
qrtr = pkgs.callPackage ./qrtr { };
|
|
||||||
|
|
||||||
"x13s/extra-firmware" = pkgs.callPackage ./extra-firmware.nix { };
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
{ stdenvNoCC, fetchFromGitHub }:
|
|
||||||
|
|
||||||
stdenvNoCC.mkDerivation {
|
|
||||||
pname = "x13s-extra-firmware";
|
|
||||||
version = "1.0.0";
|
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "ironrobin";
|
|
||||||
repo = "x13s-alarm";
|
|
||||||
rev = "efa51c3b519f75b3983aef67855b1561d9828771";
|
|
||||||
sha256 = "sha256-weETbWXz9aL2pDQDKk7fkb1ecQH0qrhUYDs2E5EiJcI=";
|
|
||||||
};
|
|
||||||
|
|
||||||
dontFixup = true;
|
|
||||||
dontBuild = true;
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/lib/firmware/qcom/sc8280xp/LENOVO/21BX
|
|
||||||
cp x13s-firmware/qcvss8280.mbn $out/lib/firmware/qcom/sc8280xp/LENOVO/21BX/
|
|
||||||
'';
|
|
||||||
}
|
|
|
@ -1,5 +1,14 @@
|
||||||
{ lib, withSystem, ... }:
|
{ lib, withSystem, ... }:
|
||||||
{
|
{
|
||||||
|
perSystem =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
packages = rec {
|
||||||
|
uefi = pkgs.callPackage ./uefi.nix { };
|
||||||
|
uefi-usbiso = pkgs.callPackage ./uefi-usbiso.nix { inherit uefi; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
flake.packages.aarch64-linux = withSystem "aarch64-linux" (
|
flake.packages.aarch64-linux = withSystem "aarch64-linux" (
|
||||||
{ pkgs, ... }: import ./default.nix { inherit lib pkgs; }
|
{ pkgs, ... }: import ./default.nix { inherit lib pkgs; }
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
{
|
|
||||||
stdenv,
|
|
||||||
lib,
|
|
||||||
fetchFromGitHub,
|
|
||||||
qrtr,
|
|
||||||
xz,
|
|
||||||
}:
|
|
||||||
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
pname = "pd-mapper";
|
|
||||||
version = "unstable-2023-09-01";
|
|
||||||
|
|
||||||
buildInputs = [
|
|
||||||
qrtr
|
|
||||||
xz
|
|
||||||
];
|
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "andersson";
|
|
||||||
repo = "pd-mapper";
|
|
||||||
rev = "10997ba7c43a3787a40b6b1b161408033e716374";
|
|
||||||
hash = "sha256-qGrYNoPCxtdpTdbkSmB39+6/pSXml96Aul8b9opF9Lc=";
|
|
||||||
};
|
|
||||||
|
|
||||||
patches = [ ./pd-mapper-firmware-path.diff ];
|
|
||||||
|
|
||||||
installFlags = [ "prefix=$(out)" ];
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
description = "Qualcomm PD mapper";
|
|
||||||
homepage = "https://github.com/andersson/pd-mapper";
|
|
||||||
license = licenses.bsd3;
|
|
||||||
mainProgram = "pd-mapper";
|
|
||||||
platforms = platforms.aarch64;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
diff --git a/pd-mapper.c b/pd-mapper.c
|
|
||||||
index 65c4b80..669d9a0 100644
|
|
||||||
--- a/pd-mapper.c
|
|
||||||
+++ b/pd-mapper.c
|
|
||||||
@@ -194,7 +194,7 @@ static int pd_load_map(const char *file)
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef ANDROID
|
|
||||||
-#define FIRMWARE_BASE "/lib/firmware/"
|
|
||||||
+#define FIRMWARE_BASE "/run/current-system/firmware/"
|
|
||||||
#else
|
|
||||||
#define FIRMWARE_BASE "/vendor/firmware/"
|
|
||||||
#endif
|
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
stdenv,
|
|
||||||
lib,
|
|
||||||
fetchFromGitHub,
|
|
||||||
}:
|
|
||||||
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
pname = "qrtr";
|
|
||||||
version = "unstable-2023-01-17";
|
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "andersson";
|
|
||||||
repo = "qrtr";
|
|
||||||
rev = "d0d471c96e7d112fac6f48bd11f9e8ce209c04d2";
|
|
||||||
hash = "sha256-KF0gCBRw3BDJdK1s+dYhHkokVTHwRFO58ho0IwHPehc=";
|
|
||||||
};
|
|
||||||
|
|
||||||
installFlags = [ "prefix=$(out)" ];
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
description = "QMI IDL compiler";
|
|
||||||
homepage = "https://github.com/andersson/qrtr";
|
|
||||||
license = licenses.bsd3;
|
|
||||||
platforms = platforms.aarch64;
|
|
||||||
};
|
|
||||||
}
|
|
50
packages/uefi-usbiso.nix
Normal file
50
packages/uefi-usbiso.nix
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
{
|
||||||
|
stdenv,
|
||||||
|
parted,
|
||||||
|
util-linux,
|
||||||
|
dosfstools,
|
||||||
|
mtools,
|
||||||
|
uefi,
|
||||||
|
}:
|
||||||
|
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
name = "usbdisk";
|
||||||
|
version = uefi.version;
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
parted
|
||||||
|
util-linux
|
||||||
|
dosfstools
|
||||||
|
mtools
|
||||||
|
];
|
||||||
|
|
||||||
|
doUnpack = false;
|
||||||
|
buildPhase = ''
|
||||||
|
img=${name}-${version}.iso
|
||||||
|
gap=8
|
||||||
|
blocks=$(du -B 512 --summarize --apparent-size ${uefi} | awk '{ print $1 }')
|
||||||
|
blocks=$(( 2 * blocks ))
|
||||||
|
size=$(( 512 * blocks + gap * 1024 * 1024 + 34*512))
|
||||||
|
truncate -s $size $img
|
||||||
|
sfdisk $img <<EOF
|
||||||
|
label: gpt
|
||||||
|
start=''${gap}M, size=$blocks, type=uefi
|
||||||
|
EOF
|
||||||
|
|
||||||
|
eval $(partx $img -o START,SECTORS --nr 1 --pairs)
|
||||||
|
truncate -s $(( SECTORS * 512 )) part.img
|
||||||
|
mkfs.vfat part.img
|
||||||
|
mcopy -spvm -i ./part.img ${uefi}/EFI "::/EFI"
|
||||||
|
mcopy -spvm -i ./part.img ${uefi}/Flash "::/Flash"
|
||||||
|
|
||||||
|
dd conv=notrunc if=part.img of=$img seek=$START count=$SECTORS
|
||||||
|
rm -fr part.img
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir $out
|
||||||
|
mv ${name}-${version}.iso $out/
|
||||||
|
'';
|
||||||
|
}
|
29
packages/uefi.nix
Normal file
29
packages/uefi.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
stdenv,
|
||||||
|
fetchurl,
|
||||||
|
innoextract,
|
||||||
|
}:
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "uefi";
|
||||||
|
version = "1.60";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://download.lenovo.com/pccbbs/mobiles/n3huj19w.exe";
|
||||||
|
hash = "sha256-ZSjkvbMb0e9CoL2OYo3Aioyz3or1YkOX/BdOOeAuL7I=";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [ innoextract ];
|
||||||
|
|
||||||
|
unpackPhase = ''
|
||||||
|
innoextract $src
|
||||||
|
'';
|
||||||
|
|
||||||
|
doBuild = false;
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir --parent $out/{EFI/Boot,Flash}
|
||||||
|
cp code\$GetExtractPath\$/Rfs/Usb/Bootaa64.efi $out/EFI/Boot/
|
||||||
|
cp -r code\$GetExtractPath\$/Rfs/Fw/* $out/Flash/
|
||||||
|
'';
|
||||||
|
}
|
55
update.py
Executable file
55
update.py
Executable file
|
@ -0,0 +1,55 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from github import Github
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
from packaging.version import Version
|
||||||
|
from subprocess import run
|
||||||
|
|
||||||
|
latest_version: str = "0"
|
||||||
|
latest_branch: str = ""
|
||||||
|
previous_version: str = ""
|
||||||
|
|
||||||
|
with Github() as gh:
|
||||||
|
for branch in gh.get_user("jhovold").get_repo("linux").get_branches():
|
||||||
|
v = re.match("wip/sc8280xp-((v?6.[0-9]+)(-rc[0-9]+)?)", branch.name)
|
||||||
|
if v != None and Version(v.group(1)) > Version(latest_version):
|
||||||
|
# add .0 to version
|
||||||
|
latest_version = f"{v.group(2)}.0{v.group(3) or ''}"
|
||||||
|
latest_branch = v.group(0)
|
||||||
|
|
||||||
|
print("branch: " + latest_branch)
|
||||||
|
print("latest: " + latest_version)
|
||||||
|
|
||||||
|
with open("packages/default.nix", "r") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
v = re.match(r'^\s*version = "(6[.0-9-rc]+)";.*$', line)
|
||||||
|
if v != None:
|
||||||
|
previous_version = v.group(1)
|
||||||
|
|
||||||
|
print("previous: " + previous_version)
|
||||||
|
|
||||||
|
if previous_version == latest_version:
|
||||||
|
print("No update found, exiting.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
with open("packages/default.nix", "w") as f:
|
||||||
|
for line in lines:
|
||||||
|
f.write(
|
||||||
|
re.sub(
|
||||||
|
r'^(\s*version = ")6[.0-9-rc]+(";.*$)',
|
||||||
|
rf"\g<1>{latest_version}\2",
|
||||||
|
line,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
run(
|
||||||
|
f"npins add --name linux-jhovold github --branch {latest_branch} jhovold linux".split(
|
||||||
|
" "
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
run("git add npins/ packages/default.nix".split(" "))
|
||||||
|
run(["git", "commit", "-m", f"jhovold: {previous_version} -> {latest_version}"])
|
Loading…
Reference in a new issue