From d5ee6fe88d7ec51b18888cdec7bec0c39cf01283 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Sat, 9 May 2026 06:50:42 +0000 Subject: [PATCH 01/39] feat: add UEFI HTTP boot support with file upload and manifest APIs --- ostool-server/src/api/models.rs | 33 ++ ostool-server/src/api/router.rs | 331 +++++++++++++++++++- ostool-server/src/config.rs | 103 +++++- ostool-server/src/http_boot.rs | 1 + ostool-server/src/http_boot/files.rs | 190 +++++++++++ ostool-server/src/lib.rs | 5 +- ostool-server/src/state.rs | 1 + ostool-server/tests/session_ws_lifecycle.rs | 2 + ostool/src/board/client.rs | 111 +++++++ 9 files changed, 769 insertions(+), 8 deletions(-) create mode 100644 ostool-server/src/http_boot.rs create mode 100644 ostool-server/src/http_boot/files.rs diff --git a/ostool-server/src/api/models.rs b/ostool-server/src/api/models.rs index 4dc1787a..5f064f3b 100644 --- a/ostool-server/src/api/models.rs +++ b/ostool-server/src/api/models.rs @@ -7,6 +7,7 @@ use crate::{ TftpConfig, TftpNetworkConfig, UploadLimitsConfig, }, dtb_store::DtbFile, + http_boot::files::HttpBootFileRef, session::Session, state::BoardLeaseState, tftp::{files::TftpFileRef, status::TftpStatus}, @@ -143,6 +144,36 @@ impl FileResponse { } } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct HttpBootFileResponse { + pub filename: String, + pub relative_path: String, + pub http_url: String, + pub size: u64, + pub uploaded_at: DateTime, +} + +impl HttpBootFileResponse { + pub fn from_file(file: HttpBootFileRef, http_url: String) -> Self { + Self { + filename: file.filename, + relative_path: file.relative_path, + http_url, + size: file.size, + uploaded_at: file.uploaded_at, + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct HttpBootManifest { + pub kernel_url: String, + pub kernel_size: u64, + pub kernel_load_addr: String, + pub entry_point: String, + pub arch: String, +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TftpSessionResponse { pub available: bool, @@ -230,6 +261,8 @@ pub struct AdminServerConfigReadonly { pub data_dir: String, pub board_dir: String, pub dtb_dir: String, + pub http_boot_root_dir: String, + pub http_boot_public_base_url: Option, pub dtb_upload_max_mib: u32, } diff --git a/ostool-server/src/api/router.rs b/ostool-server/src/api/router.rs index bc18a844..b7e85003 100644 --- a/ostool-server/src/api/router.rs +++ b/ostool-server/src/api/router.rs @@ -9,7 +9,10 @@ use axum::{ routing::{delete, get, post, put}, }; use futures_util::future::join_all; +use mime_guess::from_path; use serde_json::json; +use std::sync::Arc; +use tokio::fs; use crate::{ api::{ @@ -20,14 +23,15 @@ use crate::{ AdminSessionsResponse, AdminTftpConfigResponse, AdminTftpStatusResponse, BoardPowerAction, BoardPowerStatusResponse, BoardRuntimeStatusResponse, BoardTypeSummary, BootProfileResponse, CreateSessionRequest, DtbFileResponse, - FileResponse, NetworkInterfaceSummary, SerialPortSummary, SerialStatusResponse, - SessionCreatedResponse, SessionDetailResponse, SessionDtbResponse, TftpSessionResponse, - UpdateServerConfigRequest, + FileResponse, HttpBootFileResponse, HttpBootManifest, NetworkInterfaceSummary, + SerialPortSummary, SerialStatusResponse, SessionCreatedResponse, SessionDetailResponse, + SessionDtbResponse, TftpSessionResponse, UpdateServerConfigRequest, }, }, board_pool::BoardAllocationStatus, config::{BoardConfig, BootConfig, PowerManagementConfig, ServerConfig, TftpConfig}, dtb_store::normalize_dtb_name, + http_boot::files::{HttpBootFileRef, board_current_disk_path, put_board_current_file}, power::{PowerAction, PowerActionError}, serial::{ discovery::list_serial_ports as discover_serial_ports, @@ -38,6 +42,7 @@ use crate::{ }, ws::run_serial_ws, }, + session::SessionState, session::SessionStopReason, state::{AppState, BoardLeaseState, TouchSessionError}, tftp::{ @@ -60,6 +65,10 @@ pub fn build_router(state: AppState) -> Router { .route("/admin/", get(serve_admin_index)) .route("/admin/assets/{*path}", get(serve_admin_asset)) .route("/admin/{*path}", get(serve_admin_history)) + .route( + "/boot/boards/{board_id}/current/{*path}", + get(get_http_boot_file), + ) .route("/api/v1/admin/overview", get(get_admin_overview)) .route("/api/v1/admin/boards", get(list_boards).post(create_board)) .route("/api/v1/admin/dtbs", get(list_dtbs).post(create_dtb)) @@ -113,6 +122,14 @@ pub fn build_router(state: AppState) -> Router { "/api/v1/sessions/{session_id}/boot-profile", get(get_boot_profile), ) + .route( + "/api/v1/sessions/{session_id}/http-boot/files", + put(put_http_boot_file), + ) + .route( + "/api/v1/sessions/{session_id}/http-boot/manifest", + put(put_http_boot_manifest), + ) .route("/api/v1/sessions/{session_id}/dtb", get(get_session_dtb)) .route( "/api/v1/sessions/{session_id}/dtb/download", @@ -537,6 +554,13 @@ fn normalize_boot_config(boot: &mut BootConfig) { BootConfig::Pxe(profile) => { normalize_optional_string(&mut profile.notes); } + BootConfig::UefiHttp(profile) => { + normalize_optional_string(&mut profile.loader_file); + normalize_optional_string(&mut profile.kernel_file); + normalize_optional_string(&mut profile.kernel_load_addr); + normalize_optional_string(&mut profile.entry_point); + normalize_optional_string(&mut profile.mac_address); + } } } @@ -1089,6 +1113,96 @@ async fn power_off_board( run_board_power_action(&state, &session_id, false).await } +async fn get_http_boot_file( + Path((board_id, path)): Path<(String, String)>, + State(state): State, +) -> Result { + let relative_path = parse_relative_path(&path)?; + let config = state.config.read().await.clone(); + if !config.http_boot.enabled { + return Err(ApiError::not_found("HTTP Boot is disabled")); + } + let disk_path = board_current_disk_path(&config.http_boot.root_dir, &board_id, &relative_path) + .map_err(|err| ApiError::bad_request(err.to_string()))?; + let body = fs::read(&disk_path).await.map_err(|err| match err.kind() { + std::io::ErrorKind::NotFound => { + ApiError::not_found(format!("HTTP Boot file `{relative_path}` not found")) + } + _ => ApiError::from(anyhow::Error::from(err)), + })?; + let content_type = from_path(&disk_path).first_or_octet_stream().to_string(); + Ok(( + [( + header::CONTENT_TYPE, + HeaderValue::from_str(&content_type).map_err(|err| { + ApiError::service_unavailable(format!( + "invalid content type `{content_type}`: {err}" + )) + })?, + )], + body, + ) + .into_response()) +} + +async fn put_http_boot_file( + Path(session_id): Path, + State(state): State, + request: Request, +) -> Result<(StatusCode, axum::Json), ApiError> { + let session = active_session_state_or_404(&state, &session_id).await?; + let board = session.board().clone(); + ensure_uefi_http_board(&board)?; + let headers = request.headers(); + let relative_path = headers + .get("X-File-Path") + .and_then(|value| value.to_str().ok()) + .ok_or_else(|| ApiError::bad_request("missing X-File-Path header"))?; + let relative_path = parse_relative_path(relative_path)?; + let max_mib = state.config.read().await.upload_limits.session_file_max_mib; + let body = read_limited_body(request, max_mib, "HTTP Boot file").await?; + let config = state.config.read().await.clone(); + if !config.http_boot.enabled { + return Err(ApiError::conflict("HTTP Boot is disabled")); + } + + let file = put_board_current_file(&config.http_boot.root_dir, &board.id, &relative_path, &body) + .map_err(|err| ApiError::service_unavailable(format!("{err:#}")))?; + let response = http_boot_file_response(&config, &board.id, file)?; + Ok((StatusCode::CREATED, axum::Json(response))) +} + +async fn put_http_boot_manifest( + Path(session_id): Path, + State(state): State, + request: Request, +) -> Result<(StatusCode, axum::Json), ApiError> { + let session = active_session_state_or_404(&state, &session_id).await?; + let board = session.board().clone(); + ensure_uefi_http_board(&board)?; + let max_mib = state.config.read().await.upload_limits.session_file_max_mib; + let body = read_limited_body(request, max_mib, "HTTP Boot manifest").await?; + let manifest: HttpBootManifest = serde_json::from_slice(&body) + .map_err(|err| ApiError::bad_request(format!("invalid HTTP Boot manifest JSON: {err}")))?; + let manifest = serde_json::to_vec_pretty(&manifest).map_err(|err| { + ApiError::service_unavailable(format!("failed to encode manifest: {err}")) + })?; + let config = state.config.read().await.clone(); + if !config.http_boot.enabled { + return Err(ApiError::conflict("HTTP Boot is disabled")); + } + + let file = put_board_current_file( + &config.http_boot.root_dir, + &board.id, + "manifest.json", + &manifest, + ) + .map_err(|err| ApiError::service_unavailable(format!("{err:#}")))?; + let response = http_boot_file_response(&config, &board.id, file)?; + Ok((StatusCode::CREATED, axum::Json(response))) +} + async fn list_session_files( Path(session_id): Path, State(state): State, @@ -1300,6 +1414,65 @@ fn parse_relative_path(raw: &str) -> Result { normalize_relative_path(raw).map_err(|err| ApiError::bad_request(err.to_string())) } +async fn active_session_state_or_404( + state: &AppState, + session_id: &str, +) -> Result, ApiError> { + let session = state + .session_state(session_id) + .await + .ok_or_else(|| ApiError::not_found(format!("session `{session_id}` not found")))?; + if session.is_releasing() { + return Err(ApiError::conflict(format!( + "session `{session_id}` is releasing" + ))); + } + Ok(session) +} + +fn ensure_uefi_http_board(board: &BoardConfig) -> Result<(), ApiError> { + if matches!(board.boot, BootConfig::UefiHttp(_)) { + Ok(()) + } else { + Err(ApiError::bad_request(format!( + "board `{}` does not use `uefi_http` boot", + board.id + ))) + } +} + +fn http_boot_file_response( + config: &ServerConfig, + board_id: &str, + file: HttpBootFileRef, +) -> Result { + let prefix = format!("boards/{board_id}/current/"); + let relative_path = file + .relative_path + .strip_prefix(&prefix) + .unwrap_or(file.filename.as_str()); + let http_url = http_boot_url(config, board_id, relative_path)?; + Ok(HttpBootFileResponse::from_file(file, http_url)) +} + +fn http_boot_url( + config: &ServerConfig, + board_id: &str, + relative_path: &str, +) -> Result { + let relative_path = normalize_relative_path(relative_path) + .map_err(|err| ApiError::bad_request(err.to_string()))?; + let base_url = config + .http_boot + .public_base_url + .clone() + .unwrap_or_else(|| format!("http://{}", config.listen_addr)); + let base_url = base_url.trim_end_matches('/'); + Ok(format!( + "{base_url}/boot/boards/{board_id}/current/{relative_path}" + )) +} + fn summarize_board_types( boards: &BTreeMap, runtimes: &BTreeMap, @@ -1363,6 +1536,8 @@ fn readonly_server_config(config: &crate::config::ServerConfig) -> AdminServerCo data_dir: config.data_dir.display().to_string(), board_dir: config.board_dir.display().to_string(), dtb_dir: config.dtb_dir.display().to_string(), + http_boot_root_dir: config.http_boot.root_dir.display().to_string(), + http_boot_public_base_url: config.http_boot.public_base_url.clone(), dtb_upload_max_mib: DTB_UPLOAD_MAX_MIB, } } @@ -1584,7 +1759,8 @@ mod tests { config::{ BoardConfig, BootConfig, BuiltinTftpConfig, CustomPowerManagement, PowerManagementConfig, SerialConfig, SerialPortKey, SerialPortKeyKind, ServerConfig, - TftpConfig, UploadLimitsConfig, VirtualPowerManagement, ZhongshengRelayPowerManagement, + TftpConfig, UefiBootArch, UefiHttpProfile, UefiHttpStrategy, UploadLimitsConfig, + VirtualPowerManagement, ZhongshengRelayPowerManagement, }, session::SessionLifecycleState, state::BoardLeaseState, @@ -1613,6 +1789,7 @@ mod tests { board_dir: root.join("boards"), dtb_dir: root.join("dtbs"), tftp: TftpConfig::Builtin(BuiltinTftpConfig::default_with_root(root.join("tftp"))), + http_boot: crate::config::HttpBootConfig::default_with_root(root.join("http-boot")), network: crate::TftpNetworkConfig { interface: "lo".into(), }, @@ -1721,6 +1898,23 @@ mod tests { board } + fn sample_uefi_http_board(board_id: &str) -> BoardConfig { + let mut board = sample_virtual_board(board_id); + board.board_type = "x86_64-uefi-http".into(); + board.tags = vec!["uefi-http".into()]; + board.boot = BootConfig::UefiHttp(UefiHttpProfile { + boot_arch: Some(UefiBootArch::X86_64), + strategy: UefiHttpStrategy::BareBinLoader, + loader_file: Some("BOOTX64.EFI".into()), + kernel_file: Some("kernel.bin".into()), + kernel_load_addr: Some("0x200000".into()), + entry_point: Some("0x200000".into()), + mac_address: None, + client_ip: None, + }); + board + } + #[cfg(unix)] #[derive(Clone)] struct RecordingRelayService { @@ -1891,6 +2085,7 @@ mod tests { match board.boot { BootConfig::Uboot(profile) => assert!(profile.use_tftp), BootConfig::Pxe(_) => panic!("expected uboot"), + BootConfig::UefiHttp(_) => panic!("expected uboot"), } } @@ -2865,6 +3060,7 @@ mod tests { assert_eq!(profile.dtb_name.as_deref(), Some("board-renamed.dtb")) } BootConfig::Pxe(_) => panic!("expected uboot"), + BootConfig::UefiHttp(_) => panic!("expected uboot"), } } @@ -3020,6 +3216,133 @@ mod tests { assert_eq!(value[0]["tags"], json!(["lab-a", "lab-b", "usbboot"])); } + #[tokio::test] + async fn http_boot_upload_manifest_and_public_download_use_board_current_path() { + let app = test_router().await; + assert_eq!( + create_board( + &app, + serde_json::to_value(sample_uefi_http_board("uefi-http-01")).unwrap() + ) + .await, + StatusCode::CREATED + ); + let session_id = create_session(&app, "x86_64-uefi-http").await; + + let upload = app + .clone() + .oneshot( + Request::builder() + .method("PUT") + .uri(format!("/api/v1/sessions/{session_id}/http-boot/files")) + .header("X-File-Path", "kernel.bin") + .body(Body::from("kernel-image")) + .unwrap(), + ) + .await + .unwrap(); + assert_eq!(upload.status(), StatusCode::CREATED); + let upload_body = to_bytes(upload.into_body(), usize::MAX).await.unwrap(); + let uploaded: serde_json::Value = serde_json::from_slice(&upload_body).unwrap(); + assert_eq!(uploaded["filename"], "kernel.bin"); + assert_eq!( + uploaded["relative_path"], + "boards/uefi-http-01/current/kernel.bin" + ); + assert_eq!( + uploaded["http_url"], + "http://127.0.0.1:0/boot/boards/uefi-http-01/current/kernel.bin" + ); + + let manifest = json!({ + "kernel_url": uploaded["http_url"], + "kernel_size": 12, + "kernel_load_addr": "0x200000", + "entry_point": "0x200000", + "arch": "x86_64" + }); + let manifest_response = app + .clone() + .oneshot( + Request::builder() + .method("PUT") + .uri(format!("/api/v1/sessions/{session_id}/http-boot/manifest")) + .header(header::CONTENT_TYPE, "application/json") + .body(Body::from(manifest.to_string())) + .unwrap(), + ) + .await + .unwrap(); + assert_eq!(manifest_response.status(), StatusCode::CREATED); + let manifest_body = to_bytes(manifest_response.into_body(), usize::MAX) + .await + .unwrap(); + let manifest_uploaded: serde_json::Value = serde_json::from_slice(&manifest_body).unwrap(); + assert_eq!(manifest_uploaded["filename"], "manifest.json"); + + let download_kernel = app + .clone() + .oneshot( + Request::builder() + .uri("/boot/boards/uefi-http-01/current/kernel.bin") + .body(Body::empty()) + .unwrap(), + ) + .await + .unwrap(); + assert_eq!(download_kernel.status(), StatusCode::OK); + let kernel_body = to_bytes(download_kernel.into_body(), usize::MAX) + .await + .unwrap(); + assert_eq!(kernel_body.as_ref(), b"kernel-image"); + + let download_manifest = app + .clone() + .oneshot( + Request::builder() + .uri("/boot/boards/uefi-http-01/current/manifest.json") + .body(Body::empty()) + .unwrap(), + ) + .await + .unwrap(); + assert_eq!(download_manifest.status(), StatusCode::OK); + let downloaded_manifest = to_bytes(download_manifest.into_body(), usize::MAX) + .await + .unwrap(); + let value: serde_json::Value = serde_json::from_slice(&downloaded_manifest).unwrap(); + assert_eq!(value["arch"], "x86_64"); + assert_eq!(value["kernel_load_addr"], "0x200000"); + } + + #[tokio::test] + async fn http_boot_upload_rejects_non_uefi_http_board() { + let app = test_router().await; + assert_eq!( + create_board( + &app, + serde_json::to_value(sample_virtual_board("pxe-01")).unwrap() + ) + .await, + StatusCode::CREATED + ); + let session_id = create_session(&app, "rk3568").await; + + let response = app + .clone() + .oneshot( + Request::builder() + .method("PUT") + .uri(format!("/api/v1/sessions/{session_id}/http-boot/files")) + .header("X-File-Path", "kernel.bin") + .body(Body::from("kernel-image")) + .unwrap(), + ) + .await + .unwrap(); + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + } + #[tokio::test] async fn session_file_endpoints_support_nested_paths() { let app = test_router().await; diff --git a/ostool-server/src/config.rs b/ostool-server/src/config.rs index 0b1b356a..b0b3e24f 100644 --- a/ostool-server/src/config.rs +++ b/ostool-server/src/config.rs @@ -20,6 +20,8 @@ pub struct ServerConfig { pub board_dir: PathBuf, pub dtb_dir: PathBuf, pub tftp: TftpConfig, + #[serde(default)] + pub http_boot: HttpBootConfig, pub network: TftpNetworkConfig, #[serde(default)] pub upload_limits: UploadLimitsConfig, @@ -42,6 +44,7 @@ impl ServerConfig { }; let board_dir = data_dir.join("boards"); let dtb_dir = data_dir.join("dtbs"); + let http_boot = HttpBootConfig::default_with_root(data_dir.join("http-boot")); #[cfg(target_os = "linux")] let tftp = TftpConfig::SystemTftpdHpa(SystemTftpdHpaConfig::default()); @@ -57,6 +60,7 @@ impl ServerConfig { board_dir, dtb_dir, tftp, + http_boot, network: TftpNetworkConfig::default(), upload_limits: UploadLimitsConfig::default(), } @@ -148,6 +152,7 @@ impl ServerConfig { self.data_dir = absolutize_path(&config_dir, &self.data_dir); self.board_dir = absolutize_path(&config_dir, &self.board_dir); self.dtb_dir = absolutize_path(&config_dir, &self.dtb_dir); + self.http_boot.root_dir = absolutize_path(&config_dir, &self.http_boot.root_dir); match &mut self.tftp { TftpConfig::Builtin(cfg) => { @@ -175,6 +180,29 @@ impl ServerConfig { } } +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +pub struct HttpBootConfig { + pub enabled: bool, + pub root_dir: PathBuf, + pub public_base_url: Option, +} + +impl HttpBootConfig { + pub fn default_with_root(root_dir: PathBuf) -> Self { + Self { + enabled: true, + root_dir, + public_base_url: None, + } + } +} + +impl Default for HttpBootConfig { + fn default() -> Self { + Self::default_with_root(PathBuf::from(".ostool-server/http-boot")) + } +} + #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] pub struct UploadLimitsConfig { pub session_file_max_mib: u32, @@ -403,6 +431,7 @@ pub struct VirtualPowerManagement {} pub enum BootConfig { Uboot(UbootProfile), Pxe(PxeProfile), + UefiHttp(UefiHttpProfile), } impl BootConfig { @@ -410,6 +439,7 @@ impl BootConfig { match self { Self::Uboot(_) => "uboot", Self::Pxe(_) => "pxe", + Self::UefiHttp(_) => "uefi_http", } } } @@ -427,6 +457,35 @@ pub struct PxeProfile { pub notes: Option, } +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +pub enum UefiHttpStrategy { + BareBinLoader, +} + +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +pub enum UefiBootArch { + X86_64, + Aarch64, + Loongarch64, + Riscv64, + Other, +} + +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +#[serde(deny_unknown_fields)] +pub struct UefiHttpProfile { + pub boot_arch: Option, + pub strategy: UefiHttpStrategy, + pub loader_file: Option, + pub kernel_file: Option, + pub kernel_load_addr: Option, + pub entry_point: Option, + pub mac_address: Option, + pub client_ip: Option, +} + #[cfg(test)] mod tests { use std::{ @@ -439,8 +498,8 @@ mod tests { use super::{ BoardConfig, BootConfig, CustomPowerManagement, PowerManagementConfig, SerialPortKey, - SerialPortKeyKind, ServerConfig, UbootProfile, VirtualPowerManagement, - ZhongshengRelayPowerManagement, + SerialPortKeyKind, ServerConfig, UbootProfile, UefiBootArch, UefiHttpProfile, + UefiHttpStrategy, VirtualPowerManagement, ZhongshengRelayPowerManagement, }; #[test] @@ -452,6 +511,7 @@ mod tests { assert_eq!(decoded.network.interface, ""); assert_eq!(decoded.upload_limits.session_file_max_mib, 64); assert!(decoded.dtb_dir.ends_with("dtbs")); + assert!(decoded.http_boot.root_dir.ends_with("http-boot")); } #[test] @@ -487,6 +547,10 @@ interface = "eth0" PathBuf::from("/var/lib/ostool-server/boards") ); assert_eq!(config.dtb_dir, PathBuf::from("/var/lib/ostool-server/dtbs")); + assert_eq!( + config.http_boot.root_dir, + PathBuf::from("/var/lib/ostool-server/http-boot") + ); } #[tokio::test] @@ -502,6 +566,7 @@ interface = "eth0" let content = std::fs::read_to_string(path).unwrap(); assert!(content.contains("listen_addr = \"0.0.0.0:2999\"")); assert!(content.contains("session_file_max_mib = 64")); + assert!(content.contains("[http_boot]")); } #[test] @@ -604,6 +669,40 @@ board_power_off_cmd = "shutdown" )); } + #[test] + fn board_config_round_trip_supports_uefi_http_boot() { + let board = BoardConfig { + id: "uefi-http-01".into(), + board_type: "x86_64-uefi-http".into(), + tags: vec!["uefi-http".into()], + serial: None, + power_management: PowerManagementConfig::Virtual(VirtualPowerManagement::default()), + boot: BootConfig::UefiHttp(UefiHttpProfile { + boot_arch: Some(UefiBootArch::X86_64), + strategy: UefiHttpStrategy::BareBinLoader, + loader_file: Some("BOOTX64.EFI".into()), + kernel_file: Some("kernel.bin".into()), + kernel_load_addr: Some("0x200000".into()), + entry_point: Some("0x200000".into()), + mac_address: Some("52:54:00:12:34:56".into()), + client_ip: Some("10.3.10.215".parse().unwrap()), + }), + notes: None, + disabled: false, + }; + + let encoded = toml::to_string_pretty(&board).unwrap(); + assert!(encoded.contains("kind = \"uefi_http\"")); + assert!(encoded.contains("strategy = \"bare_bin_loader\"")); + + let decoded: BoardConfig = toml::from_str(&encoded).unwrap(); + let BootConfig::UefiHttp(profile) = decoded.boot else { + panic!("expected uefi_http"); + }; + assert_eq!(profile.boot_arch, Some(UefiBootArch::X86_64)); + assert_eq!(profile.loader_file.as_deref(), Some("BOOTX64.EFI")); + } + #[test] fn board_config_round_trip_supports_relay_power_management_key() { let board = BoardConfig { diff --git a/ostool-server/src/http_boot.rs b/ostool-server/src/http_boot.rs new file mode 100644 index 00000000..d3ab9696 --- /dev/null +++ b/ostool-server/src/http_boot.rs @@ -0,0 +1 @@ +pub mod files; diff --git a/ostool-server/src/http_boot/files.rs b/ostool-server/src/http_boot/files.rs new file mode 100644 index 00000000..c36b2556 --- /dev/null +++ b/ostool-server/src/http_boot/files.rs @@ -0,0 +1,190 @@ +use std::{ + fs, + path::{Path, PathBuf}, + time::SystemTime, +}; + +use anyhow::Context; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +use crate::tftp::files::normalize_relative_path; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct HttpBootFileRef { + pub filename: String, + #[serde(skip_serializing, skip_deserializing)] + pub disk_path: PathBuf, + pub relative_path: String, + pub size: u64, + pub uploaded_at: DateTime, +} + +pub fn board_current_relative_path(board_id: &str, relative_path: &str) -> anyhow::Result { + let board_id = normalize_board_id(board_id)?; + let normalized_relative_path = normalize_relative_path(relative_path)?; + Ok(format!( + "boards/{board_id}/current/{normalized_relative_path}" + )) +} + +pub fn board_current_disk_path( + root_dir: &Path, + board_id: &str, + relative_path: &str, +) -> anyhow::Result { + let board_id = normalize_board_id(board_id)?; + let normalized_relative_path = normalize_relative_path(relative_path)?; + Ok(board_current_root(root_dir, board_id).join(normalized_relative_path)) +} + +pub fn put_board_current_file( + root_dir: &Path, + board_id: &str, + relative_path: &str, + bytes: &[u8], +) -> anyhow::Result { + let board_id = normalize_board_id(board_id)?; + let normalized_relative_path = normalize_relative_path(relative_path)?; + let path = board_current_root(root_dir, board_id).join(&normalized_relative_path); + let parent = path + .parent() + .ok_or_else(|| anyhow::anyhow!("invalid file path: {}", path.display()))?; + fs::create_dir_all(parent).with_context(|| format!("failed to create {}", parent.display()))?; + + let temp_path = temp_path_for(&path); + fs::write(&temp_path, bytes) + .with_context(|| format!("failed to write {}", temp_path.display()))?; + fs::rename(&temp_path, &path).with_context(|| { + format!( + "failed to rename {} to {}", + temp_path.display(), + path.display() + ) + })?; + + Ok(HttpBootFileRef { + filename: filename_from_relative_path(&normalized_relative_path)?, + disk_path: path, + relative_path: board_current_relative_path(board_id, &normalized_relative_path)?, + size: bytes.len() as u64, + uploaded_at: Utc::now(), + }) +} + +pub fn get_board_current_file( + root_dir: &Path, + board_id: &str, + relative_path: &str, +) -> anyhow::Result> { + let board_id = normalize_board_id(board_id)?; + let relative_path = normalize_relative_path(relative_path)?; + let path = board_current_root(root_dir, board_id).join(&relative_path); + file_ref_from_disk(root_dir, board_id, path) +} + +fn normalize_board_id(board_id: &str) -> anyhow::Result<&str> { + let board_id = board_id.trim(); + if board_id.is_empty() { + anyhow::bail!("board id must not be empty"); + } + if board_id == "." || board_id == ".." || board_id.contains('/') || board_id.contains('\\') { + anyhow::bail!("board id must not contain path separators or dot segments"); + } + Ok(board_id) +} + +fn board_current_root(root_dir: &Path, board_id: &str) -> PathBuf { + root_dir.join("boards").join(board_id).join("current") +} + +fn filename_from_relative_path(relative_path: &str) -> anyhow::Result { + Path::new(relative_path) + .file_name() + .and_then(|name| name.to_str()) + .map(|name| name.to_string()) + .ok_or_else(|| anyhow::anyhow!("invalid file path `{relative_path}`")) +} + +fn file_ref_from_disk( + root_dir: &Path, + board_id: &str, + path: PathBuf, +) -> anyhow::Result> { + if !path.is_file() { + return Ok(None); + } + + let metadata = fs::metadata(&path)?; + let relative_disk_path = path + .strip_prefix(board_current_root(root_dir, board_id)) + .with_context(|| format!("failed to strip board current root from {}", path.display()))?; + let relative_disk_path = relative_disk_path.to_string_lossy().replace('\\', "/"); + let relative_disk_path = normalize_relative_path(&relative_disk_path)?; + let modified = metadata.modified().unwrap_or(SystemTime::UNIX_EPOCH); + + Ok(Some(HttpBootFileRef { + filename: filename_from_relative_path(&relative_disk_path)?, + disk_path: path, + relative_path: board_current_relative_path(board_id, &relative_disk_path)?, + size: metadata.len(), + uploaded_at: DateTime::::from(modified), + })) +} + +fn temp_path_for(path: &Path) -> PathBuf { + let filename = path + .file_name() + .and_then(|name| name.to_str()) + .unwrap_or("upload"); + path.with_file_name(format!("{filename}.tmp")) +} + +#[cfg(test)] +mod tests { + use std::fs; + + use tempfile::tempdir; + + use super::{ + board_current_disk_path, board_current_relative_path, get_board_current_file, + put_board_current_file, + }; + + #[test] + fn put_board_current_file_writes_stable_board_path() { + let dir = tempdir().unwrap(); + let saved = put_board_current_file(dir.path(), "demo-01", "kernel.bin", b"kernel").unwrap(); + + assert_eq!(saved.filename, "kernel.bin"); + assert_eq!(saved.relative_path, "boards/demo-01/current/kernel.bin"); + assert_eq!( + fs::read(dir.path().join("boards/demo-01/current/kernel.bin")).unwrap(), + b"kernel" + ); + + let loaded = get_board_current_file(dir.path(), "demo-01", "kernel.bin") + .unwrap() + .unwrap(); + assert_eq!(loaded.relative_path, "boards/demo-01/current/kernel.bin"); + assert_eq!( + board_current_disk_path(dir.path(), "demo-01", "kernel.bin").unwrap(), + saved.disk_path + ); + } + + #[test] + fn board_current_path_reuses_relative_path_validation() { + assert_eq!( + board_current_relative_path("demo-01", r"boot\loader.efi").unwrap(), + "boards/demo-01/current/boot/loader.efi" + ); + + for path in ["", "/kernel.bin", "../kernel.bin", "boot/"] { + assert!(board_current_relative_path("demo-01", path).is_err()); + } + for board_id in ["", ".", "..", "nested/board", r"nested\board"] { + assert!(board_current_relative_path(board_id, "kernel.bin").is_err()); + } + } +} diff --git a/ostool-server/src/lib.rs b/ostool-server/src/lib.rs index 5201035c..a28cb540 100644 --- a/ostool-server/src/lib.rs +++ b/ostool-server/src/lib.rs @@ -5,6 +5,7 @@ pub mod board_pool; pub mod board_store; pub mod config; pub mod dtb_store; +pub mod http_boot; pub mod power; pub mod process; pub mod serial; @@ -17,8 +18,8 @@ pub use api::router::build_router; pub use config::{ BoardConfig, BootConfig, BuiltinTftpConfig, CustomPowerManagement, PowerManagementConfig, PxeProfile, SerialConfig, SerialPortKey, SerialPortKeyKind, ServerConfig, SystemTftpdHpaConfig, - TftpConfig, TftpNetworkConfig, UbootProfile, UploadLimitsConfig, VirtualPowerManagement, - ZhongshengRelayPowerManagement, + TftpConfig, TftpNetworkConfig, UbootProfile, UefiBootArch, UefiHttpProfile, UefiHttpStrategy, + UploadLimitsConfig, VirtualPowerManagement, ZhongshengRelayPowerManagement, }; pub use dtb_store::{DtbFile, DtbStore}; pub use state::{AppState, BoardLeaseState, build_app_state}; diff --git a/ostool-server/src/state.rs b/ostool-server/src/state.rs index bd098893..989cb10a 100644 --- a/ostool-server/src/state.rs +++ b/ostool-server/src/state.rs @@ -340,6 +340,7 @@ impl AppState { tokio::fs::create_dir_all(&config.board_dir).await?; tokio::fs::create_dir_all(&config.dtb_dir).await?; tokio::fs::create_dir_all(config.tftp.root_dir()).await?; + tokio::fs::create_dir_all(&config.http_boot.root_dir).await?; Ok(()) } diff --git a/ostool-server/tests/session_ws_lifecycle.rs b/ostool-server/tests/session_ws_lifecycle.rs index ff4db1bb..9431dac4 100644 --- a/ostool-server/tests/session_ws_lifecycle.rs +++ b/ostool-server/tests/session_ws_lifecycle.rs @@ -104,6 +104,7 @@ fn spawn_test_server(root: &Path, serial_port: String) -> Result Result, } +#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +pub enum UefiHttpStrategy { + BareBinLoader, +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +pub enum UefiBootArch { + X86_64, + Aarch64, + Loongarch64, + Riscv64, + Other, +} + +#[derive(Debug, Clone, Deserialize)] +pub struct UefiHttpProfile { + pub boot_arch: Option, + pub strategy: UefiHttpStrategy, + pub loader_file: Option, + pub kernel_file: Option, + pub kernel_load_addr: Option, + pub entry_point: Option, + pub mac_address: Option, + pub client_ip: Option, +} + #[derive(Debug, Clone, Deserialize)] pub struct BootProfileResponse { pub boot: BootConfig, @@ -89,6 +118,24 @@ pub struct FileResponse { pub uploaded_at: DateTime, } +#[derive(Debug, Clone, Deserialize)] +pub struct HttpBootFileResponse { + pub filename: String, + pub relative_path: String, + pub http_url: String, + pub size: u64, + pub uploaded_at: DateTime, +} + +#[derive(Debug, Clone, Serialize)] +pub struct HttpBootManifest { + pub kernel_url: String, + pub kernel_size: u64, + pub kernel_load_addr: String, + pub entry_point: String, + pub arch: String, +} + #[derive(Debug, Clone, Deserialize)] pub struct TftpSessionResponse { pub available: bool, @@ -282,6 +329,38 @@ impl BoardServerClient { self.decode_json(response).await } + pub async fn upload_http_boot_file( + &self, + session_id: &str, + relative_path: &str, + bytes: Vec, + ) -> Result { + let response = self + .client + .put(self.endpoint(&format!("/api/v1/sessions/{session_id}/http-boot/files"))) + .header("X-File-Path", relative_path) + .body(bytes) + .send() + .await + .map_err(Self::request_error)?; + self.decode_json(response).await + } + + pub async fn upload_http_boot_manifest( + &self, + session_id: &str, + manifest: &HttpBootManifest, + ) -> Result { + let response = self + .client + .put(self.endpoint(&format!("/api/v1/sessions/{session_id}/http-boot/manifest"))) + .json(manifest) + .send() + .await + .map_err(Self::request_error)?; + self.decode_json(response).await + } + pub fn resolve_ws_url(&self, ws_url: &str) -> anyhow::Result { if ws_url.starts_with("ws://") || ws_url.starts_with("wss://") { return Url::parse(ws_url).with_context(|| format!("invalid websocket URL `{ws_url}`")); @@ -458,6 +537,38 @@ mod tests { assert!(profile.use_tftp); } BootConfig::Pxe(_) => panic!("expected uboot profile"), + BootConfig::UefiHttp(_) => panic!("expected uboot profile"), + } + } + + #[test] + fn parse_uefi_http_boot_profile() { + let response: super::BootProfileResponse = serde_json::from_str( + r#"{ + "boot": { + "kind": "uefi_http", + "boot_arch": "x86_64", + "strategy": "bare_bin_loader", + "loader_file": "BOOTX64.EFI", + "kernel_file": "kernel.bin", + "kernel_load_addr": "0x200000", + "entry_point": "0x200000", + "mac_address": null, + "client_ip": null + }, + "server_ip": null, + "netmask": null, + "interface": null + }"#, + ) + .unwrap(); + + match response.boot { + BootConfig::UefiHttp(profile) => { + assert_eq!(profile.boot_arch, Some(super::UefiBootArch::X86_64)); + assert_eq!(profile.loader_file.as_deref(), Some("BOOTX64.EFI")); + } + _ => panic!("expected uefi_http profile"), } } From 3c02b8506bf0665bc4cb21ceb085e5e5bb0b1855 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Sat, 9 May 2026 07:45:33 +0000 Subject: [PATCH 02/39] feat: add UEFI HTTP Boot runner with CLI and config support --- ostool/src/board/client.rs | 20 ++ ostool/src/board/mod.rs | 4 +- ostool/src/build/mod.rs | 33 +++- ostool/src/main.rs | 111 ++++++++++- ostool/src/run/httpboot.rs | 394 +++++++++++++++++++++++++++++++++++++ ostool/src/run/mod.rs | 4 + 6 files changed, 560 insertions(+), 6 deletions(-) create mode 100644 ostool/src/run/httpboot.rs diff --git a/ostool/src/board/client.rs b/ostool/src/board/client.rs index 11a0b6f7..4ce80e64 100644 --- a/ostool/src/board/client.rs +++ b/ostool/src/board/client.rs @@ -312,6 +312,26 @@ impl BoardServerClient { self.decode_bytes(response).await } + pub async fn power_on_board(&self, session_id: &str) -> Result<(), BoardServerClientError> { + let response = self + .client + .post(self.endpoint(&format!("/api/v1/sessions/{session_id}/board/power-on"))) + .send() + .await + .map_err(Self::request_error)?; + self.decode_empty(response).await + } + + pub async fn power_off_board(&self, session_id: &str) -> Result<(), BoardServerClientError> { + let response = self + .client + .post(self.endpoint(&format!("/api/v1/sessions/{session_id}/board/power-off"))) + .send() + .await + .map_err(Self::request_error)?; + self.decode_empty(response).await + } + pub async fn upload_session_file( &self, session_id: &str, diff --git a/ostool/src/board/mod.rs b/ostool/src/board/mod.rs index 295f1523..db7ade1e 100644 --- a/ostool/src/board/mod.rs +++ b/ostool/src/board/mod.rs @@ -150,7 +150,7 @@ pub async fn connect_board(server: &str, port: u16, board_type: &str) -> anyhow: finalize_session(session, result).await } -fn print_allocated_board_session(session: &BoardSession, board_type: &str) { +pub(crate) fn print_allocated_board_session(session: &BoardSession, board_type: &str) { println!("Allocated board session:"); println!(" board_type: {board_type}"); println!(" board_id: {}", session.info().board_id); @@ -159,7 +159,7 @@ fn print_allocated_board_session(session: &BoardSession, board_type: &str) { println!(" boot_mode: {}", session.info().boot_mode); } -async fn finalize_session( +pub(crate) async fn finalize_session( session: BoardSession, run_result: anyhow::Result<()>, ) -> anyhow::Result<()> { diff --git a/ostool/src/build/mod.rs b/ostool/src/build/mod.rs index 82248787..000b7a80 100644 --- a/ostool/src/build/mod.rs +++ b/ostool/src/build/mod.rs @@ -6,7 +6,7 @@ //! - Configuring build options via TOML configuration files //! - Running pre-build and post-build shell commands //! - Automatic feature detection and configuration -//! - Multiple runner types (QEMU, U-Boot) +//! - Multiple runner types (QEMU, U-Boot, UEFI HTTP Boot) //! //! # Example //! @@ -27,6 +27,7 @@ use crate::{ config::{Cargo, Custom}, }, run::{ + httpboot::{HttpBootConfig, RunHttpBootOptions}, qemu::{QemuConfig, RunQemuOptions}, uboot::{RunUbootOptions, UbootConfig}, }, @@ -62,15 +63,26 @@ pub struct CargoUbootRunnerArgs { pub show_output: bool, } +/// Parameters for running a built Cargo artifact via UEFI HTTP Boot. +#[derive(Debug, Clone, Default)] +pub struct CargoHttpbootRunnerArgs { + /// Optional fully prepared HTTP Boot runtime configuration. + pub httpboot: Option, + /// Whether to show HTTP Boot output. + pub show_output: bool, +} + /// Specifies the type of runner to use after building. /// /// This enum determines how the built artifact will be executed, -/// either through QEMU emulation or via U-Boot on real hardware. +/// through QEMU emulation, U-Boot, or UEFI HTTP Boot on real hardware. pub enum CargoRunnerKind { /// Run the built artifact in QEMU emulator. Qemu(Box), /// Run the built artifact on real hardware via U-Boot. Uboot(Box), + /// Publish and run the built artifact via UEFI HTTP Boot. + Httpboot(Box), } impl CargoRunnerKind { @@ -81,6 +93,10 @@ impl CargoRunnerKind { pub fn new_uboot(args: CargoUbootRunnerArgs) -> Self { Self::Uboot(Box::new(args)) } + + pub fn new_httpboot(args: CargoHttpbootRunnerArgs) -> Self { + Self::Httpboot(Box::new(args)) + } } impl Tool { @@ -253,6 +269,19 @@ impl Tool { ) .await?; } + CargoRunnerKind::Httpboot(args) => { + let httpboot = match &args.httpboot { + Some(config) => config.clone(), + None => self.ensure_httpboot_config_for_cargo(config).await?, + }; + self.run_httpboot( + &httpboot, + RunHttpBootOptions { + show_output: args.show_output, + }, + ) + .await?; + } } Ok(()) diff --git a/ostool/src/main.rs b/ostool/src/main.rs index 9504e298..754c853e 100644 --- a/ostool/src/main.rs +++ b/ostool/src/main.rs @@ -8,10 +8,13 @@ use env_logger::Env; use log::info; use ostool::{ ManifestContext, Tool, ToolConfig, board, - build::{self, CargoQemuRunnerArgs, CargoRunnerKind, CargoUbootRunnerArgs}, + build::{ + self, CargoHttpbootRunnerArgs, CargoQemuRunnerArgs, CargoRunnerKind, CargoUbootRunnerArgs, + }, menuconfig::{MenuConfigHandler, MenuConfigMode}, resolve_manifest_context, run::{ + httpboot::{HttpBootConfig, RunHttpBootOptions}, qemu::{QemuConfig, RunQemuOptions}, uboot::{RunUbootOptions, UbootConfig}, }, @@ -115,6 +118,7 @@ struct BoardConnectArgs { enum RunSubCommands { Qemu(RunQemuCommand), Uboot(RunUbootCommand), + Httpboot(RunHttpbootCommand), } #[derive(Args, Debug, Default)] @@ -142,6 +146,22 @@ pub struct UbootArgs { uboot_config: Option, } +#[derive(Args, Debug)] +struct RunHttpbootCommand { + /// Path to the build configuration file + #[arg(short, long)] + config: Option, + #[command(flatten)] + httpboot: HttpbootArgs, +} + +#[derive(Args, Debug)] +pub struct HttpbootArgs { + /// Path to the HTTP Boot configuration file, default to '.httpboot.toml' + #[arg(long = "httpboot-config")] + httpboot_config: Option, +} + #[tokio::main] async fn main() -> ExitCode { match try_main().await { @@ -286,6 +306,48 @@ async fn try_main() -> Result<()> { } } } + RunSubCommands::Httpboot(args) => { + let RunHttpbootCommand { config, httpboot } = args; + + let (mut tool, manifest_ctx) = init_tool(manifest.clone())?; + let build_config = + load_build_config(&mut tool, &manifest_ctx, config.as_deref()).await?; + match &build_config.system { + build::config::BuildSystem::Cargo(config) => { + let httpboot_config = match httpboot.httpboot_config.as_deref() { + Some(path) => Some( + tool.read_httpboot_config_from_path_for_cargo(config, path) + .await?, + ), + None => None, + }; + let kind = CargoRunnerKind::new_httpboot(CargoHttpbootRunnerArgs { + httpboot: httpboot_config, + show_output: true, + }); + tool.cargo_run(config, &kind).await?; + } + build::config::BuildSystem::Custom(custom_cfg) => { + tool.build_with_config(&build_config).await?; + tool.prepare_elf_artifact( + custom_cfg.elf_path.clone().into(), + custom_cfg.to_bin, + ) + .await?; + let httpboot_config = load_httpboot_config( + &mut tool, + &manifest_ctx, + httpboot.httpboot_config.as_deref(), + ) + .await?; + tool.run_httpboot( + &httpboot_config, + RunHttpBootOptions { show_output: true }, + ) + .await?; + } + } + } }, SubCommands::Menuconfig { mode } => { let (mut tool, _) = init_tool(manifest)?; @@ -349,6 +411,20 @@ async fn load_uboot_config( } } +async fn load_httpboot_config( + tool: &mut Tool, + manifest: &ManifestContext, + config_path: Option<&std::path::Path>, +) -> Result { + match config_path { + Some(path) => tool.read_httpboot_config_from_path(path).await, + None => { + tool.ensure_httpboot_config_in_dir(&manifest.workspace_dir) + .await + } + } +} + async fn load_board_config( tool: &mut Tool, manifest: &ManifestContext, @@ -375,7 +451,7 @@ fn report_error(err: &anyhow::Error) { mod tests { use clap::Parser; - use super::{BoardArgs, BoardSubCommands, Cli, SubCommands}; + use super::{BoardArgs, BoardSubCommands, Cli, RunSubCommands, SubCommands}; #[test] fn parse_board_ls_with_server_args() { @@ -502,6 +578,37 @@ mod tests { } } + #[test] + fn parse_run_httpboot_command() { + let cli = Cli::try_parse_from([ + "ostool", + "run", + "httpboot", + "--config", + "board.build.toml", + "--httpboot-config", + "remote.httpboot.toml", + ]) + .unwrap(); + + match cli.command { + SubCommands::Run { command } => match command { + RunSubCommands::Httpboot(args) => { + assert_eq!( + args.config.as_deref(), + Some(std::path::Path::new("board.build.toml")) + ); + assert_eq!( + args.httpboot.httpboot_config.as_deref(), + Some(std::path::Path::new("remote.httpboot.toml")) + ); + } + other => panic!("expected run httpboot, got {other:?}"), + }, + other => panic!("expected run command, got {other:?}"), + } + } + #[test] fn parse_board_config_command() { let cli = Cli::try_parse_from(["ostool", "board", "config"]).unwrap(); diff --git a/ostool/src/run/httpboot.rs b/ostool/src/run/httpboot.rs new file mode 100644 index 00000000..4099705e --- /dev/null +++ b/ostool/src/run/httpboot.rs @@ -0,0 +1,394 @@ +use std::{ + io, + path::{Path, PathBuf}, +}; + +use anyhow::Context as _; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use tokio::fs; + +use crate::{ + Tool, + board::{ + acquire_board_session, + client::{ + BoardServerClient, BootConfig as RemoteBootConfig, HttpBootManifest, + SessionCreatedResponse, UefiBootArch, + }, + finalize_session, load_board_global_config_with_notice, print_allocated_board_session, + session::BoardSession, + terminal, + }, + utils::PathResultExt, +}; + +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)] +pub struct HttpBootConfig { + pub board_type: String, + pub server: Option, + pub port: Option, + pub remote_name: Option, + pub kernel_load_addr: String, + pub entry_point: String, + #[serde(default = "default_power_cycle")] + pub power_cycle: bool, + #[serde(default = "default_open_console")] + pub open_console: bool, +} + +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct RunHttpBootOptions { + pub show_output: bool, +} + +fn default_power_cycle() -> bool { + true +} + +fn default_open_console() -> bool { + true +} + +impl HttpBootConfig { + fn replace_strings(&mut self, tool: &Tool) -> anyhow::Result<()> { + self.board_type = tool.replace_string(&self.board_type)?; + self.server = self + .server + .as_deref() + .map(|value| tool.replace_string(value)) + .transpose()?; + self.remote_name = self + .remote_name + .as_deref() + .map(|value| tool.replace_string(value)) + .transpose()?; + self.kernel_load_addr = tool.replace_string(&self.kernel_load_addr)?; + self.entry_point = tool.replace_string(&self.entry_point)?; + Ok(()) + } + + fn normalize(&mut self, config_name: &str) -> anyhow::Result<()> { + normalize_required_string(&mut self.board_type, "board_type", config_name)?; + normalize_required_string(&mut self.kernel_load_addr, "kernel_load_addr", config_name)?; + normalize_required_string(&mut self.entry_point, "entry_point", config_name)?; + normalize_optional_string(&mut self.server); + normalize_optional_string(&mut self.remote_name); + Ok(()) + } +} + +impl Tool { + pub fn default_httpboot_config(&self) -> HttpBootConfig { + HttpBootConfig { + board_type: "x86_64-uefi-http".to_string(), + remote_name: Some("kernel.bin".to_string()), + kernel_load_addr: "0x200000".to_string(), + entry_point: "0x200000".to_string(), + power_cycle: true, + open_console: true, + ..Default::default() + } + } + + pub async fn read_httpboot_config_from_path_for_cargo( + &mut self, + cargo: &crate::build::config::Cargo, + path: &Path, + ) -> anyhow::Result { + self.sync_cargo_context(cargo); + let config_path = self.replace_path_variables(path.to_path_buf())?; + read_httpboot_config_at_path(self, config_path).await + } + + pub async fn ensure_httpboot_config_for_cargo( + &mut self, + cargo: &crate::build::config::Cargo, + ) -> anyhow::Result { + self.sync_cargo_context(cargo); + let workspace_dir = self.workspace_dir().clone(); + self.ensure_httpboot_config_in_dir_for_cargo(cargo, &workspace_dir) + .await + } + + pub async fn ensure_httpboot_config_in_dir_for_cargo( + &mut self, + cargo: &crate::build::config::Cargo, + dir: &Path, + ) -> anyhow::Result { + self.sync_cargo_context(cargo); + let dir = self.replace_path_variables(dir.to_path_buf())?; + ensure_httpboot_config_at_path( + self, + dir.join(".httpboot.toml"), + self.default_httpboot_config(), + ) + .await + } + + pub async fn ensure_httpboot_config_in_dir( + &mut self, + dir: &Path, + ) -> anyhow::Result { + let dir = self.replace_path_variables(dir.to_path_buf())?; + ensure_httpboot_config_at_path( + self, + dir.join(".httpboot.toml"), + self.default_httpboot_config(), + ) + .await + } + + pub async fn read_httpboot_config_from_path( + &mut self, + path: &Path, + ) -> anyhow::Result { + let config_path = self.replace_path_variables(path.to_path_buf())?; + read_httpboot_config_at_path(self, config_path).await + } + + pub async fn run_httpboot( + &mut self, + config: &HttpBootConfig, + options: RunHttpBootOptions, + ) -> anyhow::Result<()> { + let _ = options.show_output; + let mut config = config.clone(); + config.replace_strings(self)?; + config.normalize("HTTP Boot runtime config")?; + + let kernel_bin = self.objcopy_output_bin()?; + let global_config = load_board_global_config_with_notice()?; + let (server, port) = global_config.resolve_server(config.server.as_deref(), config.port); + let (client, session) = acquire_board_session(&server, port, &config.board_type).await?; + print_allocated_board_session(&session, &config.board_type); + + let run_result = run_httpboot_session(&client, session.info(), &config, &kernel_bin).await; + let run_result = finish_httpboot_session(&client, &session, &config, run_result).await; + finalize_session(session, run_result).await + } +} + +async fn read_httpboot_config_at_path( + tool: &Tool, + config_path: PathBuf, +) -> anyhow::Result { + let mut config: HttpBootConfig = fs::read_to_string(&config_path) + .await + .with_context(|| format!("failed to read HTTP Boot config: {}", config_path.display())) + .and_then(|content| { + toml::from_str(&content).with_context(|| { + format!( + "failed to parse HTTP Boot config: {}", + config_path.display() + ) + }) + })?; + config.replace_strings(tool)?; + config.normalize(&format!("HTTP Boot config {}", config_path.display()))?; + Ok(config) +} + +async fn ensure_httpboot_config_at_path( + tool: &Tool, + config_path: PathBuf, + default_config: HttpBootConfig, +) -> anyhow::Result { + let mut config = match fs::read_to_string(&config_path).await { + Ok(_) => return read_httpboot_config_at_path(tool, config_path).await, + Err(err) if err.kind() == io::ErrorKind::NotFound => { + let config = default_config; + fs::write(&config_path, toml::to_string_pretty(&config)?) + .await + .with_path("failed to write file", &config_path)?; + config + } + Err(err) => return Err(err.into()), + }; + + config.replace_strings(tool)?; + config.normalize(&format!("HTTP Boot config {}", config_path.display()))?; + Ok(config) +} + +struct HttpBootPublishedUrls { + loader_url: String, + manifest_url: String, + kernel_url: String, +} + +async fn finish_httpboot_session( + client: &BoardServerClient, + session: &BoardSession, + config: &HttpBootConfig, + run_result: anyhow::Result, +) -> anyhow::Result<()> { + let urls = run_result?; + println!("HTTP Boot artifacts published:"); + println!(" loader_url: {}", urls.loader_url); + println!(" manifest_url: {}", urls.manifest_url); + println!(" kernel_url: {}", urls.kernel_url); + + if config.power_cycle { + client + .power_off_board(&session.info().session_id) + .await + .context("failed to power off board")?; + client + .power_on_board(&session.info().session_id) + .await + .context("failed to power on board")?; + } + + if !config.open_console { + return Ok(()); + } + + if session.info().serial_available { + let ws_path = session + .info() + .ws_url + .as_deref() + .ok_or_else(|| anyhow::anyhow!("server did not return a serial websocket URL"))?; + let ws_url = client.resolve_ws_url(ws_path)?; + terminal::run_serial_terminal(ws_url).await + } else { + println!("Board has no serial configuration; HTTP Boot artifacts are ready."); + Ok(()) + } +} + +async fn run_httpboot_session( + client: &BoardServerClient, + session: &SessionCreatedResponse, + config: &HttpBootConfig, + kernel_bin: &Path, +) -> anyhow::Result { + if session.boot_mode != "uefi_http" { + anyhow::bail!( + "unsupported remote boot mode `{}`; only `uefi_http` is supported", + session.boot_mode + ); + } + + let boot_profile = client + .get_boot_profile(&session.session_id) + .await + .context("failed to get HTTP Boot profile")?; + let RemoteBootConfig::UefiHttp(profile) = boot_profile.boot else { + anyhow::bail!("server returned a non-uefi_http boot profile"); + }; + + let remote_name = config + .remote_name + .clone() + .or(profile.kernel_file.clone()) + .or_else(|| { + kernel_bin + .file_name() + .and_then(|name| name.to_str()) + .map(str::to_string) + }) + .ok_or_else(|| anyhow::anyhow!("failed to determine remote kernel filename"))?; + + let kernel_bytes = std::fs::read(kernel_bin) + .with_context(|| format!("failed to read {}", kernel_bin.display()))?; + let kernel_size = kernel_bytes.len() as u64; + let uploaded = client + .upload_http_boot_file(&session.session_id, &remote_name, kernel_bytes) + .await + .with_context(|| format!("failed to upload HTTP Boot file `{remote_name}`"))?; + + let arch = profile + .boot_arch + .as_ref() + .map(uefi_boot_arch_name) + .unwrap_or("other") + .to_string(); + let manifest = HttpBootManifest { + kernel_url: uploaded.http_url.clone(), + kernel_size, + kernel_load_addr: config.kernel_load_addr.clone(), + entry_point: config.entry_point.clone(), + arch, + }; + let manifest_file = client + .upload_http_boot_manifest(&session.session_id, &manifest) + .await + .context("failed to upload HTTP Boot manifest")?; + + let loader_file = profile + .loader_file + .as_deref() + .ok_or_else(|| anyhow::anyhow!("uefi_http boot profile is missing `loader_file`"))?; + let loader_url = manifest_file + .http_url + .trim_end_matches("manifest.json") + .to_string() + + loader_file; + + Ok(HttpBootPublishedUrls { + loader_url, + manifest_url: manifest_file.http_url, + kernel_url: uploaded.http_url, + }) +} + +fn uefi_boot_arch_name(arch: &UefiBootArch) -> &'static str { + match arch { + UefiBootArch::X86_64 => "x86_64", + UefiBootArch::Aarch64 => "aarch64", + UefiBootArch::Loongarch64 => "loongarch64", + UefiBootArch::Riscv64 => "riscv64", + UefiBootArch::Other => "other", + } +} + +fn normalize_required_string( + value: &mut String, + field_name: &str, + config_name: &str, +) -> anyhow::Result<()> { + let trimmed = value.trim(); + if trimmed.is_empty() { + anyhow::bail!("`{field_name}` must not be empty in {config_name}"); + } + if trimmed.len() != value.len() { + *value = trimmed.to_string(); + } + Ok(()) +} + +fn normalize_optional_string(value: &mut Option) { + if let Some(raw) = value { + let trimmed = raw.trim(); + if trimmed.is_empty() { + *value = None; + } else if trimmed.len() != raw.len() { + *raw = trimmed.to_string(); + } + } +} + +#[cfg(test)] +mod tests { + use super::HttpBootConfig; + + #[test] + fn httpboot_config_normalizes_required_fields() { + let mut config = HttpBootConfig { + board_type: " x86_64-uefi-http ".into(), + kernel_load_addr: " 0x200000 ".into(), + entry_point: " 0x200000 ".into(), + remote_name: Some(" kernel.bin ".into()), + ..Default::default() + }; + + config.normalize("test").unwrap(); + + assert_eq!(config.board_type, "x86_64-uefi-http"); + assert_eq!(config.kernel_load_addr, "0x200000"); + assert_eq!(config.entry_point, "0x200000"); + assert_eq!(config.remote_name.as_deref(), Some("kernel.bin")); + } +} diff --git a/ostool/src/run/mod.rs b/ostool/src/run/mod.rs index e4b4b285..71f6e742 100644 --- a/ostool/src/run/mod.rs +++ b/ostool/src/run/mod.rs @@ -5,8 +5,12 @@ //! //! - [`qemu`] - Running in QEMU emulator with UEFI support //! - [`tftp`] - TFTP server for network booting +//! - [`httpboot`] - UEFI HTTP Boot publishing via ostool-server //! - [`uboot`] - U-Boot bootloader integration via serial/YMODEM +/// UEFI HTTP Boot publishing via ostool-server. +pub mod httpboot; + /// QEMU emulator runner with UEFI/OVMF support. pub mod qemu; From 0f240a8694df2b1fdef9961c87c84fdd6d2938a1 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Sat, 9 May 2026 08:23:14 +0000 Subject: [PATCH 03/39] feat: support efi_loader_path config for HTTP Boot runner --- ostool/src/run/httpboot.rs | 115 +++++++++++++++++++++++++++++++++---- 1 file changed, 104 insertions(+), 11 deletions(-) diff --git a/ostool/src/run/httpboot.rs b/ostool/src/run/httpboot.rs index 4099705e..f8165f28 100644 --- a/ostool/src/run/httpboot.rs +++ b/ostool/src/run/httpboot.rs @@ -29,6 +29,7 @@ pub struct HttpBootConfig { pub server: Option, pub port: Option, pub remote_name: Option, + pub efi_loader_path: Option, pub kernel_load_addr: String, pub entry_point: String, #[serde(default = "default_power_cycle")] @@ -63,6 +64,11 @@ impl HttpBootConfig { .as_deref() .map(|value| tool.replace_string(value)) .transpose()?; + self.efi_loader_path = self + .efi_loader_path + .as_deref() + .map(|value| tool.replace_string(value)) + .transpose()?; self.kernel_load_addr = tool.replace_string(&self.kernel_load_addr)?; self.entry_point = tool.replace_string(&self.entry_point)?; Ok(()) @@ -74,6 +80,7 @@ impl HttpBootConfig { normalize_required_string(&mut self.entry_point, "entry_point", config_name)?; normalize_optional_string(&mut self.server); normalize_optional_string(&mut self.remote_name); + normalize_optional_string(&mut self.efi_loader_path); Ok(()) } } @@ -312,20 +319,28 @@ async fn run_httpboot_session( entry_point: config.entry_point.clone(), arch, }; - let manifest_file = client - .upload_http_boot_manifest(&session.session_id, &manifest) - .await - .context("failed to upload HTTP Boot manifest")?; - let loader_file = profile .loader_file .as_deref() .ok_or_else(|| anyhow::anyhow!("uefi_http boot profile is missing `loader_file`"))?; - let loader_url = manifest_file - .http_url - .trim_end_matches("manifest.json") - .to_string() - + loader_file; + let uploaded_loader = upload_configured_loader( + client, + &session.session_id, + loader_file, + config.efi_loader_path.as_deref(), + ) + .await?; + let manifest_file = client + .upload_http_boot_manifest(&session.session_id, &manifest) + .await + .context("failed to upload HTTP Boot manifest")?; + let loader_url = if let Some(loader) = uploaded_loader { + loader.http_url + } else { + let loader_url = sibling_http_boot_url(&manifest_file.http_url, loader_file)?; + verify_existing_loader_url(&loader_url).await?; + loader_url + }; Ok(HttpBootPublishedUrls { loader_url, @@ -334,6 +349,61 @@ async fn run_httpboot_session( }) } +async fn upload_configured_loader( + client: &BoardServerClient, + session_id: &str, + loader_file: &str, + efi_loader_path: Option<&str>, +) -> anyhow::Result> { + let Some(efi_loader_path) = efi_loader_path else { + return Ok(None); + }; + + let loader_bytes = std::fs::read(efi_loader_path) + .with_context(|| format!("failed to read HTTP Boot loader {}", efi_loader_path))?; + let uploaded = client + .upload_http_boot_file(session_id, loader_file, loader_bytes) + .await + .with_context(|| { + format!("failed to upload HTTP Boot loader `{loader_file}` from `{efi_loader_path}`") + })?; + Ok(Some(uploaded)) +} + +async fn verify_existing_loader_url(loader_url: &str) -> anyhow::Result<()> { + let response = reqwest::get(loader_url) + .await + .with_context(|| format!("failed to verify HTTP Boot loader URL `{loader_url}`"))?; + let status = response.status(); + if !status.is_success() { + anyhow::bail!( + "HTTP Boot loader URL `{loader_url}` returned {status}; set `efi_loader_path` in .httpboot.toml or pre-publish the loader" + ); + } + Ok(()) +} + +fn sibling_http_boot_url(current_file_url: &str, relative_path: &str) -> anyhow::Result { + if relative_path.trim().is_empty() + || relative_path.starts_with('/') + || relative_path + .split('/') + .any(|component| component.is_empty() || component == "." || component == "..") + { + anyhow::bail!("invalid HTTP Boot relative path `{relative_path}`"); + } + let base = reqwest::Url::parse(current_file_url) + .with_context(|| format!("invalid HTTP Boot URL `{current_file_url}`"))? + .join("./") + .with_context(|| { + format!("failed to resolve HTTP Boot base URL from `{current_file_url}`") + })?; + Ok(base + .join(relative_path) + .with_context(|| format!("failed to resolve HTTP Boot URL for `{relative_path}`"))? + .to_string()) +} + fn uefi_boot_arch_name(arch: &UefiBootArch) -> &'static str { match arch { UefiBootArch::X86_64 => "x86_64", @@ -372,7 +442,7 @@ fn normalize_optional_string(value: &mut Option) { #[cfg(test)] mod tests { - use super::HttpBootConfig; + use super::{HttpBootConfig, sibling_http_boot_url}; #[test] fn httpboot_config_normalizes_required_fields() { @@ -381,6 +451,7 @@ mod tests { kernel_load_addr: " 0x200000 ".into(), entry_point: " 0x200000 ".into(), remote_name: Some(" kernel.bin ".into()), + efi_loader_path: Some(" BOOTX64.EFI ".into()), ..Default::default() }; @@ -390,5 +461,27 @@ mod tests { assert_eq!(config.kernel_load_addr, "0x200000"); assert_eq!(config.entry_point, "0x200000"); assert_eq!(config.remote_name.as_deref(), Some("kernel.bin")); + assert_eq!(config.efi_loader_path.as_deref(), Some("BOOTX64.EFI")); + } + + #[test] + fn sibling_http_boot_url_resolves_loader_in_current_dir() { + let url = sibling_http_boot_url( + "http://127.0.0.1:2999/boot/boards/demo/current/manifest.json", + "BOOTX64.EFI", + ) + .unwrap(); + + assert_eq!( + url, + "http://127.0.0.1:2999/boot/boards/demo/current/BOOTX64.EFI" + ); + } + + #[test] + fn sibling_http_boot_url_rejects_absolute_or_dot_paths() { + for path in ["/BOOTX64.EFI", "../BOOTX64.EFI", "boot/../BOOTX64.EFI"] { + assert!(sibling_http_boot_url("http://127.0.0.1/manifest.json", path).is_err()); + } } } From 1bd9446d901969d9755d8836a1f0160f14ff9808 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Sat, 9 May 2026 08:35:13 +0000 Subject: [PATCH 04/39] feat: add httpboot-loader crate with no-std manifest parser and UEFI stub --- Cargo.lock | 4 + Cargo.toml | 9 +- httpboot-loader/Cargo.toml | 23 +++++ httpboot-loader/README.md | 24 +++++ httpboot-loader/src/lib.rs | 194 ++++++++++++++++++++++++++++++++++++ httpboot-loader/src/main.rs | 99 ++++++++++++++++++ ostool/src/main.rs | 12 +++ ostool/src/menuconfig.rs | 40 ++++++++ 8 files changed, 404 insertions(+), 1 deletion(-) create mode 100644 httpboot-loader/Cargo.toml create mode 100644 httpboot-loader/README.md create mode 100644 httpboot-loader/src/lib.rs create mode 100644 httpboot-loader/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index d3f73497..26c94746 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1290,6 +1290,10 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "httpboot-loader" +version = "0.1.0" + [[package]] name = "httpdate" version = "1.0.3" diff --git a/Cargo.toml b/Cargo.toml index 523c4430..fb1056f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,13 @@ [workspace] exclude = ["assets/*", "fit_test"] -members = ["ostool", "uboot-shell", "jkconfig", "fitimage", "ostool-server"] +members = [ + "ostool", + "uboot-shell", + "jkconfig", + "fitimage", + "ostool-server", + "httpboot-loader", +] resolver = "3" [workspace.dependencies] diff --git a/httpboot-loader/Cargo.toml b/httpboot-loader/Cargo.toml new file mode 100644 index 00000000..536ceb5a --- /dev/null +++ b/httpboot-loader/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "httpboot-loader" +authors = ["柏乔森 "] +categories = ["command-line-interface", "config"] +description = "UEFI HTTP Boot bare-bin loader for ostool" +edition = "2024" +keywords = ["ostool", "uefi", "http boot", "loader"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/drivercraft/ostool" +version = "0.1.0" +publish = false + +[lib] +path = "src/lib.rs" + +[[bin]] +name = "httpboot-loader" +path = "src/main.rs" +required-features = ["uefi-app"] + +[features] +default = [] +uefi-app = [] diff --git a/httpboot-loader/README.md b/httpboot-loader/README.md new file mode 100644 index 00000000..0d940e62 --- /dev/null +++ b/httpboot-loader/README.md @@ -0,0 +1,24 @@ +# ostool HTTP Boot Loader + +This crate contains the UEFI-side loader for `ostool run httpboot`. + +Current status: + +- The shared no-std core parses `manifest.json`. +- The `uefi-app` binary builds a minimal UEFI application stub for targets that Rust supports, such as `x86_64-unknown-uefi`. +- HTTP download, memory placement, UEFI Boot Services shutdown, cache handling, and the architecture-specific jump backend are intentionally kept as the next implementation boundary. + +Build the x86_64 stub after installing the target: + +```bash +rustup target add x86_64-unknown-uefi +cargo build -p httpboot-loader --features uefi-app --target x86_64-unknown-uefi +mkdir -p target/httpboot-loader +cp target/x86_64-unknown-uefi/debug/httpboot-loader.efi target/httpboot-loader/BOOTX64.EFI +``` + +Then set: + +```toml +efi_loader_path = "target/httpboot-loader/BOOTX64.EFI" +``` diff --git a/httpboot-loader/src/lib.rs b/httpboot-loader/src/lib.rs new file mode 100644 index 00000000..07652b2a --- /dev/null +++ b/httpboot-loader/src/lib.rs @@ -0,0 +1,194 @@ +#![no_std] + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct BootManifest<'a> { + pub kernel_url: &'a str, + pub kernel_size: u64, + pub kernel_load_addr: u64, + pub entry_point: u64, + pub arch: &'a str, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ManifestError { + MissingField(&'static str), + InvalidJson(&'static str), + InvalidNumber(&'static str), +} + +pub fn parse_manifest(input: &str) -> Result, ManifestError> { + Ok(BootManifest { + kernel_url: json_string_field(input, "kernel_url")?, + kernel_size: json_u64_field(input, "kernel_size")?, + kernel_load_addr: parse_addr(json_string_field(input, "kernel_load_addr")?) + .map_err(|_| ManifestError::InvalidNumber("kernel_load_addr"))?, + entry_point: parse_addr(json_string_field(input, "entry_point")?) + .map_err(|_| ManifestError::InvalidNumber("entry_point"))?, + arch: json_string_field(input, "arch")?, + }) +} + +pub fn parse_addr(input: &str) -> Result { + let value = input.trim(); + let (radix, digits) = if let Some(hex) = value + .strip_prefix("0x") + .or_else(|| value.strip_prefix("0X")) + { + (16, hex) + } else { + (10, value) + }; + + parse_u64_digits(digits, radix) +} + +fn json_string_field<'a>(input: &'a str, key: &'static str) -> Result<&'a str, ManifestError> { + let value = field_value(input, key)?; + parse_json_string(value).ok_or(ManifestError::InvalidJson(key)) +} + +fn json_u64_field(input: &str, key: &'static str) -> Result { + let value = field_value(input, key)?; + let end = value + .bytes() + .position(|byte| !byte.is_ascii_digit() && byte != b'_') + .unwrap_or(value.len()); + if end == 0 { + return Err(ManifestError::InvalidNumber(key)); + } + parse_u64_digits(&value[..end], 10).map_err(|_| ManifestError::InvalidNumber(key)) +} + +fn field_value<'a>(input: &'a str, key: &'static str) -> Result<&'a str, ManifestError> { + let key_start = find_json_key(input, key).ok_or(ManifestError::MissingField(key))?; + let after_key = &input[key_start + key.len() + 2..]; + let colon = after_key + .bytes() + .position(|byte| byte == b':') + .ok_or(ManifestError::InvalidJson(key))?; + Ok(after_key[colon + 1..].trim_start()) +} + +fn find_json_key(input: &str, key: &str) -> Option { + let quoted_len = key.len() + 2; + let bytes = input.as_bytes(); + let mut index = 0; + + while index + quoted_len <= bytes.len() { + if bytes[index] == b'"' + && input[index + 1..].starts_with(key) + && bytes.get(index + quoted_len - 1) == Some(&b'"') + { + return Some(index); + } + index += 1; + } + + None +} + +fn parse_json_string(input: &str) -> Option<&str> { + let bytes = input.as_bytes(); + if bytes.first() != Some(&b'"') { + return None; + } + + let mut index = 1; + while index < bytes.len() { + match bytes[index] { + b'\\' => return None, + b'"' => return Some(&input[1..index]), + _ => index += 1, + } + } + + None +} + +fn parse_u64_digits(input: &str, radix: u32) -> Result { + let mut value = 0u64; + let mut saw_digit = false; + + for byte in input.bytes() { + if byte == b'_' { + continue; + } + let digit = match byte { + b'0'..=b'9' => (byte - b'0') as u32, + b'a'..=b'f' => (byte - b'a' + 10) as u32, + b'A'..=b'F' => (byte - b'A' + 10) as u32, + _ => return Err(()), + }; + if digit >= radix { + return Err(()); + } + value = value + .checked_mul(radix as u64) + .and_then(|value| value.checked_add(digit as u64)) + .ok_or(())?; + saw_digit = true; + } + + saw_digit.then_some(value).ok_or(()) +} + +#[cfg(test)] +extern crate std; + +#[cfg(test)] +mod tests { + use super::{BootManifest, ManifestError, parse_addr, parse_manifest}; + + #[test] + fn parses_server_manifest() { + let manifest = parse_manifest( + r#"{ + "kernel_url": "http://127.0.0.1:2999/boot/boards/demo/current/kernel.bin", + "kernel_size": 123456, + "kernel_load_addr": "0x20_3008_0000", + "entry_point": "0x20_3008_0000", + "arch": "loongarch64" + }"#, + ) + .unwrap(); + + assert_eq!( + manifest, + BootManifest { + kernel_url: "http://127.0.0.1:2999/boot/boards/demo/current/kernel.bin", + kernel_size: 123456, + kernel_load_addr: 0x20_3008_0000, + entry_point: 0x20_3008_0000, + arch: "loongarch64", + } + ); + } + + #[test] + fn parses_decimal_and_hex_addresses() { + assert_eq!(parse_addr("2097152"), Ok(0x20_0000)); + assert_eq!(parse_addr("0x20_0000"), Ok(0x20_0000)); + } + + #[test] + fn rejects_missing_fields() { + let err = parse_manifest(r#"{"kernel_size": 1}"#).unwrap_err(); + assert_eq!(err, ManifestError::MissingField("kernel_url")); + } + + #[test] + fn rejects_escaped_manifest_strings_for_now() { + let err = parse_manifest( + r#"{ + "kernel_url": "http:\/\/127.0.0.1\/kernel.bin", + "kernel_size": 1, + "kernel_load_addr": "0x200000", + "entry_point": "0x200000", + "arch": "x86_64" + }"#, + ) + .unwrap_err(); + + assert_eq!(err, ManifestError::InvalidJson("kernel_url")); + } +} diff --git a/httpboot-loader/src/main.rs b/httpboot-loader/src/main.rs new file mode 100644 index 00000000..d86fc71c --- /dev/null +++ b/httpboot-loader/src/main.rs @@ -0,0 +1,99 @@ +#![cfg_attr(target_os = "uefi", no_main)] +#![cfg_attr(target_os = "uefi", no_std)] + +#[cfg(not(target_os = "uefi"))] +compile_error!("the uefi-app feature must be built with a *-unknown-uefi target"); + +#[cfg(target_os = "uefi")] +use core::{ffi::c_void, panic::PanicInfo}; + +#[cfg(target_os = "uefi")] +type EfiHandle = *mut c_void; + +#[cfg(target_os = "uefi")] +#[repr(transparent)] +#[derive(Clone, Copy)] +pub struct EfiStatus(usize); + +#[cfg(target_os = "uefi")] +const EFI_SUCCESS: EfiStatus = EfiStatus(0); +#[cfg(target_os = "uefi")] +const EFI_UNSUPPORTED: EfiStatus = EfiStatus(3); + +#[cfg(target_os = "uefi")] +#[repr(C)] +struct EfiTableHeader { + signature: u64, + revision: u32, + header_size: u32, + crc32: u32, + reserved: u32, +} + +#[cfg(target_os = "uefi")] +#[repr(C)] +struct EfiSimpleTextOutputProtocol { + reset: usize, + output_string: + extern "efiapi" fn(this: *mut EfiSimpleTextOutputProtocol, string: *const u16) -> EfiStatus, +} + +#[cfg(target_os = "uefi")] +#[repr(C)] +pub struct EfiSystemTable { + hdr: EfiTableHeader, + firmware_vendor: *mut u16, + firmware_revision: u32, + console_in_handle: EfiHandle, + con_in: *mut c_void, + console_out_handle: EfiHandle, + con_out: *mut EfiSimpleTextOutputProtocol, +} + +#[cfg(target_os = "uefi")] +#[unsafe(no_mangle)] +pub extern "efiapi" fn efi_main(_image: EfiHandle, system_table: *mut EfiSystemTable) -> EfiStatus { + let Some(console) = (unsafe { system_table.as_mut() }).and_then(|table| { + let console = table.con_out; + unsafe { console.as_mut() } + }) else { + return EFI_UNSUPPORTED; + }; + + write_console(console, "ostool HTTP Boot loader\r\n"); + write_console(console, "manifest parser core linked\r\n"); + write_console( + console, + "HTTP download and architecture jump backend are not enabled in this build\r\n", + ); + + EFI_SUCCESS +} + +#[cfg(target_os = "uefi")] +fn write_console(console: *mut EfiSimpleTextOutputProtocol, message: &str) { + let Some(console_ref) = (unsafe { console.as_mut() }) else { + return; + }; + + let mut buffer = [0u16; 192]; + let mut index = 0; + for unit in message.encode_utf16() { + if index + 1 >= buffer.len() { + break; + } + buffer[index] = unit; + index += 1; + } + buffer[index] = 0; + + (console_ref.output_string)(console, buffer.as_ptr()); +} + +#[cfg(target_os = "uefi")] +#[panic_handler] +fn panic(_info: &PanicInfo<'_>) -> ! { + loop { + core::hint::spin_loop(); + } +} diff --git a/ostool/src/main.rs b/ostool/src/main.rs index 754c853e..10929777 100644 --- a/ostool/src/main.rs +++ b/ostool/src/main.rs @@ -609,6 +609,18 @@ mod tests { } } + #[test] + fn parse_menuconfig_httpboot_command() { + let cli = Cli::try_parse_from(["ostool", "menuconfig", "httpboot"]).unwrap(); + + match cli.command { + SubCommands::Menuconfig { mode } => { + assert!(matches!(mode, Some(super::MenuConfigMode::Httpboot))); + } + other => panic!("expected menuconfig command, got {other:?}"), + } + } + #[test] fn parse_board_config_command() { let cli = Cli::try_parse_from(["ostool", "board", "config"]).unwrap(); diff --git a/ostool/src/menuconfig.rs b/ostool/src/menuconfig.rs index 69ea1035..b2bf1afa 100644 --- a/ostool/src/menuconfig.rs +++ b/ostool/src/menuconfig.rs @@ -7,6 +7,7 @@ //! - Build settings (`.build.toml`) //! - QEMU settings (`.qemu.toml`) //! - U-Boot settings (`.uboot.toml`) +//! - UEFI HTTP Boot settings (`.httpboot.toml`) use anyhow::Context; use anyhow::Result; @@ -16,6 +17,7 @@ use tokio::fs; use crate::Tool; use crate::build::config::BuildConfig; +use crate::run::httpboot::HttpBootConfig; use crate::run::qemu::QemuConfig; use crate::run::uboot::UbootConfig; use crate::utils::PathResultExt; @@ -27,6 +29,8 @@ pub enum MenuConfigMode { Qemu, /// Configure U-Boot runner settings. Uboot, + /// Configure UEFI HTTP Boot runner settings. + Httpboot, } /// Handler for menu configuration operations. @@ -52,6 +56,9 @@ impl MenuConfigHandler { Some(MenuConfigMode::Uboot) => { Self::handle_uboot_config(tool).await?; } + Some(MenuConfigMode::Httpboot) => { + Self::handle_httpboot_config(tool).await?; + } None => { Self::handle_default_config(tool).await?; } @@ -135,6 +142,39 @@ impl MenuConfigHandler { Ok(()) } + + async fn handle_httpboot_config(tool: &mut Tool) -> Result<()> { + info!("配置 UEFI HTTP Boot 运行参数"); + + let httpboot_config_path = tool.workspace_dir().join(".httpboot.toml"); + if httpboot_config_path.exists() { + println!( + "\n当前 HTTP Boot 配置文件: {}", + httpboot_config_path.display() + ); + } else { + println!("\n未找到 HTTP Boot 配置文件,将使用默认配置"); + } + + let config = jkconfig::run::(httpboot_config_path.clone(), true, &[]) + .await + .with_context(|| { + format!( + "failed to load HTTP Boot config: {}", + httpboot_config_path.display() + ) + })?; + if let Some(c) = config { + fs::write(&httpboot_config_path, toml::to_string_pretty(&c)?) + .await + .with_path("failed to write file", &httpboot_config_path)?; + println!("\nHTTP Boot 配置已保存到 .httpboot.toml"); + } else { + println!("\n未更改 HTTP Boot 配置"); + } + + Ok(()) + } } #[cfg(test)] From 78361da89439befe21d298e1aa0fb00041f31a94 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 11 May 2026 07:39:59 +0000 Subject: [PATCH 05/39] feat: extract URI from UEFI device path and derive sibling manifest URL --- httpboot-loader/README.md | 2 + httpboot-loader/src/lib.rs | 124 ++++++++++++++++++++++++- httpboot-loader/src/main.rs | 175 +++++++++++++++++++++++++++++++++++- 3 files changed, 297 insertions(+), 4 deletions(-) diff --git a/httpboot-loader/README.md b/httpboot-loader/README.md index 0d940e62..bcd713d7 100644 --- a/httpboot-loader/README.md +++ b/httpboot-loader/README.md @@ -5,7 +5,9 @@ This crate contains the UEFI-side loader for `ostool run httpboot`. Current status: - The shared no-std core parses `manifest.json`. +- The shared no-std core can extract a URI device path and derive the sibling `manifest.json` URL. - The `uefi-app` binary builds a minimal UEFI application stub for targets that Rust supports, such as `x86_64-unknown-uefi`. +- The stub opens Loaded Image Protocol, reads its file path URI, and prints the derived manifest URL. - HTTP download, memory placement, UEFI Boot Services shutdown, cache handling, and the architecture-specific jump backend are intentionally kept as the next implementation boundary. Build the x86_64 stub after installing the target: diff --git a/httpboot-loader/src/lib.rs b/httpboot-loader/src/lib.rs index 07652b2a..c6539cfe 100644 --- a/httpboot-loader/src/lib.rs +++ b/httpboot-loader/src/lib.rs @@ -1,5 +1,7 @@ #![no_std] +use core::str; + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BootManifest<'a> { pub kernel_url: &'a str, @@ -16,6 +18,16 @@ pub enum ManifestError { InvalidNumber(&'static str), } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum UrlError { + EmptyUrl, + MissingPathSeparator, + OutputTooSmall, + MalformedDevicePath, + NonUtf8Uri, + UriNotFound, +} + pub fn parse_manifest(input: &str) -> Result, ManifestError> { Ok(BootManifest { kernel_url: json_string_field(input, "kernel_url")?, @@ -28,6 +40,62 @@ pub fn parse_manifest(input: &str) -> Result, ManifestError> { }) } +pub fn write_sibling_manifest_url<'a>( + loader_url: &str, + output: &'a mut [u8], +) -> Result<&'a str, UrlError> { + let loader_url = loader_url.trim(); + if loader_url.is_empty() { + return Err(UrlError::EmptyUrl); + } + + let slash = loader_url + .rfind('/') + .ok_or(UrlError::MissingPathSeparator)?; + let prefix = &loader_url[..slash + 1]; + let needed = prefix.len() + b"manifest.json".len(); + if needed > output.len() { + return Err(UrlError::OutputTooSmall); + } + + output[..prefix.len()].copy_from_slice(prefix.as_bytes()); + output[prefix.len()..needed].copy_from_slice(b"manifest.json"); + + str::from_utf8(&output[..needed]).map_err(|_| UrlError::NonUtf8Uri) +} + +pub fn uri_from_device_path(device_path: &[u8]) -> Result<&str, UrlError> { + const DEVICE_PATH_TYPE_MESSAGING: u8 = 0x03; + const DEVICE_PATH_TYPE_END: u8 = 0x7f; + const DEVICE_PATH_SUBTYPE_URI: u8 = 0x18; + const DEVICE_PATH_SUBTYPE_END_ENTIRE: u8 = 0xff; + + let mut offset = 0; + let mut uri = None; + + while offset + 4 <= device_path.len() { + let node_type = device_path[offset]; + let node_subtype = device_path[offset + 1]; + let node_len = + u16::from_le_bytes([device_path[offset + 2], device_path[offset + 3]]) as usize; + if node_len < 4 || offset + node_len > device_path.len() { + return Err(UrlError::MalformedDevicePath); + } + + if node_type == DEVICE_PATH_TYPE_MESSAGING && node_subtype == DEVICE_PATH_SUBTYPE_URI { + let payload = trim_trailing_nul(&device_path[offset + 4..offset + node_len]); + uri = Some(str::from_utf8(payload).map_err(|_| UrlError::NonUtf8Uri)?); + } + + offset += node_len; + if node_type == DEVICE_PATH_TYPE_END && node_subtype == DEVICE_PATH_SUBTYPE_END_ENTIRE { + return uri.ok_or(UrlError::UriNotFound); + } + } + + Err(UrlError::MalformedDevicePath) +} + pub fn parse_addr(input: &str) -> Result { let value = input.trim(); let (radix, digits) = if let Some(hex) = value @@ -42,6 +110,13 @@ pub fn parse_addr(input: &str) -> Result { parse_u64_digits(digits, radix) } +fn trim_trailing_nul(bytes: &[u8]) -> &[u8] { + match bytes.iter().rposition(|byte| *byte != 0) { + Some(last) => &bytes[..=last], + None => &[], + } +} + fn json_string_field<'a>(input: &'a str, key: &'static str) -> Result<&'a str, ManifestError> { let value = field_value(input, key)?; parse_json_string(value).ok_or(ManifestError::InvalidJson(key)) @@ -137,7 +212,10 @@ extern crate std; #[cfg(test)] mod tests { - use super::{BootManifest, ManifestError, parse_addr, parse_manifest}; + use super::{ + BootManifest, ManifestError, UrlError, parse_addr, parse_manifest, uri_from_device_path, + write_sibling_manifest_url, + }; #[test] fn parses_server_manifest() { @@ -191,4 +269,48 @@ mod tests { assert_eq!(err, ManifestError::InvalidJson("kernel_url")); } + + #[test] + fn builds_manifest_url_next_to_loader_url() { + let mut output = [0u8; 128]; + let manifest_url = write_sibling_manifest_url( + "http://127.0.0.1:2999/boot/boards/demo/current/BOOTX64.EFI", + &mut output, + ) + .unwrap(); + + assert_eq!( + manifest_url, + "http://127.0.0.1:2999/boot/boards/demo/current/manifest.json" + ); + } + + #[test] + fn rejects_manifest_url_output_that_is_too_small() { + let mut output = [0u8; 8]; + let err = write_sibling_manifest_url("http://host/BOOTX64.EFI", &mut output).unwrap_err(); + assert_eq!(err, UrlError::OutputTooSmall); + } + + #[test] + fn extracts_uri_from_device_path() { + let uri = b"http://host/current/BOOTX64.EFI"; + let uri_node_len = (4 + uri.len()) as u16; + let mut path = std::vec::Vec::new(); + path.extend_from_slice(&[0x03, 0x18]); + path.extend_from_slice(&uri_node_len.to_le_bytes()); + path.extend_from_slice(uri); + path.extend_from_slice(&[0x7f, 0xff, 0x04, 0x00]); + + assert_eq!( + uri_from_device_path(&path), + Ok("http://host/current/BOOTX64.EFI") + ); + } + + #[test] + fn rejects_device_path_without_uri() { + let path = [0x7f, 0xff, 0x04, 0x00]; + assert_eq!(uri_from_device_path(&path), Err(UrlError::UriNotFound)); + } } diff --git a/httpboot-loader/src/main.rs b/httpboot-loader/src/main.rs index d86fc71c..88f883d1 100644 --- a/httpboot-loader/src/main.rs +++ b/httpboot-loader/src/main.rs @@ -7,18 +7,42 @@ compile_error!("the uefi-app feature must be built with a *-unknown-uefi target" #[cfg(target_os = "uefi")] use core::{ffi::c_void, panic::PanicInfo}; +#[cfg(target_os = "uefi")] +use httpboot_loader::{uri_from_device_path, write_sibling_manifest_url}; + #[cfg(target_os = "uefi")] type EfiHandle = *mut c_void; #[cfg(target_os = "uefi")] #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct EfiStatus(usize); #[cfg(target_os = "uefi")] const EFI_SUCCESS: EfiStatus = EfiStatus(0); #[cfg(target_os = "uefi")] const EFI_UNSUPPORTED: EfiStatus = EfiStatus(3); +#[cfg(target_os = "uefi")] +const EFI_LOADED_IMAGE_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x5b1b31a1, + data2: 0x9562, + data3: 0x11d2, + data4: [0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], +}; + +#[cfg(target_os = "uefi")] +const DEVICE_PATH_BUFFER_SIZE: usize = 1024; +#[cfg(target_os = "uefi")] +const URL_BUFFER_SIZE: usize = 1024; + +#[cfg(target_os = "uefi")] +#[repr(C)] +struct EfiGuid { + data1: u32, + data2: u16, + data3: u16, + data4: [u8; 8], +} #[cfg(target_os = "uefi")] #[repr(C)] @@ -38,6 +62,36 @@ struct EfiSimpleTextOutputProtocol { extern "efiapi" fn(this: *mut EfiSimpleTextOutputProtocol, string: *const u16) -> EfiStatus, } +#[cfg(target_os = "uefi")] +#[repr(C)] +struct EfiBootServices { + hdr: EfiTableHeader, + _reserved_before_handle_protocol: [usize; 16], + handle_protocol: extern "efiapi" fn( + handle: EfiHandle, + protocol: *const EfiGuid, + interface: *mut *mut c_void, + ) -> EfiStatus, +} + +#[cfg(target_os = "uefi")] +#[repr(C)] +struct EfiDevicePathProtocol { + node_type: u8, + node_subtype: u8, + length: [u8; 2], +} + +#[cfg(target_os = "uefi")] +#[repr(C)] +struct EfiLoadedImageProtocol { + revision: u32, + parent_handle: EfiHandle, + system_table: *mut EfiSystemTable, + device_handle: EfiHandle, + file_path: *const EfiDevicePathProtocol, +} + #[cfg(target_os = "uefi")] #[repr(C)] pub struct EfiSystemTable { @@ -48,11 +102,15 @@ pub struct EfiSystemTable { con_in: *mut c_void, console_out_handle: EfiHandle, con_out: *mut EfiSimpleTextOutputProtocol, + standard_error_handle: EfiHandle, + std_err: *mut EfiSimpleTextOutputProtocol, + runtime_services: *mut c_void, + boot_services: *mut EfiBootServices, } #[cfg(target_os = "uefi")] #[unsafe(no_mangle)] -pub extern "efiapi" fn efi_main(_image: EfiHandle, system_table: *mut EfiSystemTable) -> EfiStatus { +pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTable) -> EfiStatus { let Some(console) = (unsafe { system_table.as_mut() }).and_then(|table| { let console = table.con_out; unsafe { console.as_mut() } @@ -62,14 +120,125 @@ pub extern "efiapi" fn efi_main(_image: EfiHandle, system_table: *mut EfiSystemT write_console(console, "ostool HTTP Boot loader\r\n"); write_console(console, "manifest parser core linked\r\n"); + + let mut device_path_buffer = [0u8; DEVICE_PATH_BUFFER_SIZE]; + let mut manifest_url_buffer = [0u8; URL_BUFFER_SIZE]; + match loader_url_from_loaded_image(image, system_table, &mut device_path_buffer) { + Ok(loader_url) => { + write_console(console, "loader_url: "); + write_console(console, loader_url); + write_console(console, "\r\n"); + + match write_sibling_manifest_url(loader_url, &mut manifest_url_buffer) { + Ok(manifest_url) => { + write_console(console, "manifest_url: "); + write_console(console, manifest_url); + write_console(console, "\r\n"); + } + Err(_) => write_console(console, "failed to build manifest URL\r\n"), + } + } + Err(LoaderError::ProtocolUnavailable) => { + write_console(console, "failed to open Loaded Image Protocol\r\n") + } + Err(LoaderError::MissingFilePath) => { + write_console(console, "loaded image has no file path\r\n") + } + Err(LoaderError::DevicePathTooLarge) => { + write_console(console, "loaded image device path is too large\r\n") + } + Err(LoaderError::InvalidDevicePath) => { + write_console(console, "loaded image device path has no URI\r\n") + } + } + write_console( console, - "HTTP download and architecture jump backend are not enabled in this build\r\n", + "HTTP download backend is not enabled in this build\r\n", ); EFI_SUCCESS } +#[cfg(target_os = "uefi")] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum LoaderError { + ProtocolUnavailable, + MissingFilePath, + DevicePathTooLarge, + InvalidDevicePath, +} + +#[cfg(target_os = "uefi")] +fn loader_url_from_loaded_image<'a>( + image: EfiHandle, + system_table: *mut EfiSystemTable, + buffer: &'a mut [u8], +) -> Result<&'a str, LoaderError> { + let boot_services = (unsafe { system_table.as_mut() }) + .map(|table| table.boot_services) + .and_then(|boot_services| unsafe { boot_services.as_mut() }) + .ok_or(LoaderError::ProtocolUnavailable)?; + + let mut interface = core::ptr::null_mut(); + let status = + (boot_services.handle_protocol)(image, &EFI_LOADED_IMAGE_PROTOCOL_GUID, &mut interface); + if status.is_error() || interface.is_null() { + return Err(LoaderError::ProtocolUnavailable); + } + + let loaded_image = unsafe { (interface as *mut EfiLoadedImageProtocol).as_ref() } + .ok_or(LoaderError::ProtocolUnavailable)?; + if loaded_image.file_path.is_null() { + return Err(LoaderError::MissingFilePath); + } + + let size = copy_device_path_to_buffer(loaded_image.file_path, buffer)?; + uri_from_device_path(&buffer[..size]).map_err(|_| LoaderError::InvalidDevicePath) +} + +#[cfg(target_os = "uefi")] +fn copy_device_path_to_buffer( + device_path: *const EfiDevicePathProtocol, + buffer: &mut [u8], +) -> Result { + let mut offset = 0; + let mut current = device_path; + + loop { + let node = unsafe { current.as_ref() }.ok_or(LoaderError::MissingFilePath)?; + let node_len = u16::from_le_bytes(node.length) as usize; + if node_len < 4 { + return Err(LoaderError::InvalidDevicePath); + } + if offset + node_len > buffer.len() { + return Err(LoaderError::DevicePathTooLarge); + } + + unsafe { + core::ptr::copy_nonoverlapping( + current as *const u8, + buffer.as_mut_ptr().add(offset), + node_len, + ); + } + offset += node_len; + + if node.node_type == 0x7f && node.node_subtype == 0xff { + return Ok(offset); + } + + current = unsafe { (current as *const u8).add(node_len) as *const EfiDevicePathProtocol }; + } +} + +#[cfg(target_os = "uefi")] +impl EfiStatus { + fn is_error(self) -> bool { + self.0 & (1usize << (usize::BITS - 1)) != 0 + } +} + #[cfg(target_os = "uefi")] fn write_console(console: *mut EfiSimpleTextOutputProtocol, message: &str) { let Some(console_ref) = (unsafe { console.as_mut() }) else { From 8b62838409b21c3642a70b5443782bd024e9b724 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 11 May 2026 07:55:28 +0000 Subject: [PATCH 06/39] feat: add downloaded manifest byte parser with validation --- httpboot-loader/src/lib.rs | 78 ++++++++++++++++++++++++++++++++++++- httpboot-loader/src/main.rs | 2 +- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/httpboot-loader/src/lib.rs b/httpboot-loader/src/lib.rs index c6539cfe..1accfb2d 100644 --- a/httpboot-loader/src/lib.rs +++ b/httpboot-loader/src/lib.rs @@ -18,6 +18,14 @@ pub enum ManifestError { InvalidNumber(&'static str), } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DownloadError { + EmptyBody, + BodyTooLarge, + NonUtf8Body, + InvalidManifest(ManifestError), +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum UrlError { EmptyUrl, @@ -40,6 +48,21 @@ pub fn parse_manifest(input: &str) -> Result, ManifestError> { }) } +pub fn parse_downloaded_manifest( + body: &[u8], + max_len: usize, +) -> Result, DownloadError> { + if body.is_empty() { + return Err(DownloadError::EmptyBody); + } + if body.len() > max_len { + return Err(DownloadError::BodyTooLarge); + } + + let manifest = str::from_utf8(body).map_err(|_| DownloadError::NonUtf8Body)?; + parse_manifest(manifest).map_err(DownloadError::InvalidManifest) +} + pub fn write_sibling_manifest_url<'a>( loader_url: &str, output: &'a mut [u8], @@ -213,8 +236,8 @@ extern crate std; #[cfg(test)] mod tests { use super::{ - BootManifest, ManifestError, UrlError, parse_addr, parse_manifest, uri_from_device_path, - write_sibling_manifest_url, + BootManifest, DownloadError, ManifestError, UrlError, parse_addr, + parse_downloaded_manifest, parse_manifest, uri_from_device_path, write_sibling_manifest_url, }; #[test] @@ -270,6 +293,57 @@ mod tests { assert_eq!(err, ManifestError::InvalidJson("kernel_url")); } + #[test] + fn parses_downloaded_manifest_bytes() { + let manifest = parse_downloaded_manifest( + br#"{ + "kernel_url": "http://127.0.0.1:2999/kernel.bin", + "kernel_size": 4096, + "kernel_load_addr": "0x200000", + "entry_point": "0x200000", + "arch": "x86_64" + }"#, + 1024, + ) + .unwrap(); + + assert_eq!(manifest.kernel_url, "http://127.0.0.1:2999/kernel.bin"); + assert_eq!(manifest.kernel_size, 4096); + assert_eq!(manifest.kernel_load_addr, 0x20_0000); + assert_eq!(manifest.entry_point, 0x20_0000); + assert_eq!(manifest.arch, "x86_64"); + } + + #[test] + fn rejects_empty_or_oversized_downloaded_manifest() { + assert_eq!( + parse_downloaded_manifest(b"", 1024), + Err(DownloadError::EmptyBody) + ); + assert_eq!( + parse_downloaded_manifest(br#"{"kernel_size":1}"#, 4), + Err(DownloadError::BodyTooLarge) + ); + } + + #[test] + fn rejects_non_utf8_downloaded_manifest() { + assert_eq!( + parse_downloaded_manifest(&[0xff, 0xfe], 1024), + Err(DownloadError::NonUtf8Body) + ); + } + + #[test] + fn wraps_downloaded_manifest_parse_errors() { + assert_eq!( + parse_downloaded_manifest(br#"{"kernel_size":1}"#, 1024), + Err(DownloadError::InvalidManifest( + ManifestError::MissingField("kernel_url") + )) + ); + } + #[test] fn builds_manifest_url_next_to_loader_url() { let mut output = [0u8; 128]; diff --git a/httpboot-loader/src/main.rs b/httpboot-loader/src/main.rs index 88f883d1..7db07956 100644 --- a/httpboot-loader/src/main.rs +++ b/httpboot-loader/src/main.rs @@ -154,7 +154,7 @@ pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTa write_console( console, - "HTTP download backend is not enabled in this build\r\n", + "HTTP download backend is pending; manifest bytes parser linked\r\n", ); EFI_SUCCESS From 168519c691eef35dd40eb6158d536a22ecb49e63 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 11 May 2026 08:07:15 +0000 Subject: [PATCH 07/39] feat: probe EFI HTTP protocol availability via locate_handle_buffer --- httpboot-loader/src/main.rs | 154 ++++++++++++++++++++++++++++++++++-- 1 file changed, 149 insertions(+), 5 deletions(-) diff --git a/httpboot-loader/src/main.rs b/httpboot-loader/src/main.rs index 7db07956..1a4a77f7 100644 --- a/httpboot-loader/src/main.rs +++ b/httpboot-loader/src/main.rs @@ -29,6 +29,20 @@ const EFI_LOADED_IMAGE_PROTOCOL_GUID: EfiGuid = EfiGuid { data3: 0x11d2, data4: [0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], }; +#[cfg(target_os = "uefi")] +const EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0xbdc8e6af, + data2: 0xd9bc, + data3: 0x4379, + data4: [0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c], +}; +#[cfg(target_os = "uefi")] +const EFI_HTTP_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x7a59b29b, + data2: 0x910b, + data3: 0x4171, + data4: [0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b], +}; #[cfg(target_os = "uefi")] const DEVICE_PATH_BUFFER_SIZE: usize = 1024; @@ -66,12 +80,53 @@ struct EfiSimpleTextOutputProtocol { #[repr(C)] struct EfiBootServices { hdr: EfiTableHeader, - _reserved_before_handle_protocol: [usize; 16], + _raise_tpl: usize, + _restore_tpl: usize, + _allocate_pages: usize, + _free_pages: usize, + _get_memory_map: usize, + _allocate_pool: usize, + free_pool: extern "efiapi" fn(buffer: *mut c_void) -> EfiStatus, + _create_event: usize, + _set_timer: usize, + _wait_for_event: usize, + _signal_event: usize, + _close_event: usize, + _check_event: usize, + _install_protocol_interface: usize, + _reinstall_protocol_interface: usize, + _uninstall_protocol_interface: usize, handle_protocol: extern "efiapi" fn( handle: EfiHandle, protocol: *const EfiGuid, interface: *mut *mut c_void, ) -> EfiStatus, + _reserved: usize, + _register_protocol_notify: usize, + _locate_handle: usize, + _locate_device_path: usize, + _install_configuration_table: usize, + _load_image: usize, + _start_image: usize, + _exit: usize, + _unload_image: usize, + _exit_boot_services: usize, + _get_next_monotonic_count: usize, + _stall: usize, + _set_watchdog_timer: usize, + _connect_controller: usize, + _disconnect_controller: usize, + _open_protocol: usize, + _close_protocol: usize, + _open_protocol_information: usize, + _protocols_per_handle: usize, + locate_handle_buffer: extern "efiapi" fn( + search_type: EfiLocateSearchType, + protocol: *const EfiGuid, + search_key: *mut c_void, + no_handles: *mut usize, + buffer: *mut *mut EfiHandle, + ) -> EfiStatus, } #[cfg(target_os = "uefi")] @@ -92,6 +147,11 @@ struct EfiLoadedImageProtocol { file_path: *const EfiDevicePathProtocol, } +#[cfg(target_os = "uefi")] +type EfiLocateSearchType = u32; +#[cfg(target_os = "uefi")] +const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; + #[cfg(target_os = "uefi")] #[repr(C)] pub struct EfiSystemTable { @@ -156,6 +216,7 @@ pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTa console, "HTTP download backend is pending; manifest bytes parser linked\r\n", ); + print_http_protocol_probe(console, system_table); EFI_SUCCESS } @@ -169,16 +230,75 @@ enum LoaderError { InvalidDevicePath, } +#[cfg(target_os = "uefi")] +fn print_http_protocol_probe( + console: *mut EfiSimpleTextOutputProtocol, + system_table: *mut EfiSystemTable, +) { + let Some(boot_services) = boot_services_from_system_table(system_table) else { + write_console(console, "failed to access Boot Services for HTTP probe\r\n"); + return; + }; + + match count_protocol_handles(boot_services, &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID) { + Ok(count) => { + write_console(console, "http_service_binding_handles: "); + write_usize(console, count); + write_console(console, "\r\n"); + } + Err(_) => write_console(console, "failed to locate HTTP Service Binding Protocol\r\n"), + } + + match count_protocol_handles(boot_services, &EFI_HTTP_PROTOCOL_GUID) { + Ok(count) => { + write_console(console, "http_protocol_handles: "); + write_usize(console, count); + write_console(console, "\r\n"); + } + Err(_) => write_console(console, "failed to locate HTTP Protocol\r\n"), + } +} + +#[cfg(target_os = "uefi")] +fn boot_services_from_system_table( + system_table: *mut EfiSystemTable, +) -> Option<&'static mut EfiBootServices> { + (unsafe { system_table.as_mut() }) + .map(|table| table.boot_services) + .and_then(|boot_services| unsafe { boot_services.as_mut() }) +} + +#[cfg(target_os = "uefi")] +fn count_protocol_handles( + boot_services: &mut EfiBootServices, + protocol: &EfiGuid, +) -> Result { + let mut handle_count = 0usize; + let mut handles = core::ptr::null_mut(); + let status = (boot_services.locate_handle_buffer)( + EFI_LOCATE_BY_PROTOCOL, + protocol, + core::ptr::null_mut(), + &mut handle_count, + &mut handles, + ); + if status.is_error() { + return Err(status); + } + if !handles.is_null() { + let _ = (boot_services.free_pool)(handles as *mut c_void); + } + Ok(handle_count) +} + #[cfg(target_os = "uefi")] fn loader_url_from_loaded_image<'a>( image: EfiHandle, system_table: *mut EfiSystemTable, buffer: &'a mut [u8], ) -> Result<&'a str, LoaderError> { - let boot_services = (unsafe { system_table.as_mut() }) - .map(|table| table.boot_services) - .and_then(|boot_services| unsafe { boot_services.as_mut() }) - .ok_or(LoaderError::ProtocolUnavailable)?; + let boot_services = + boot_services_from_system_table(system_table).ok_or(LoaderError::ProtocolUnavailable)?; let mut interface = core::ptr::null_mut(); let status = @@ -259,6 +379,30 @@ fn write_console(console: *mut EfiSimpleTextOutputProtocol, message: &str) { (console_ref.output_string)(console, buffer.as_ptr()); } +#[cfg(target_os = "uefi")] +fn write_usize(console: *mut EfiSimpleTextOutputProtocol, mut value: usize) { + let mut digits = [0u8; 20]; + let mut len = 0; + + if value == 0 { + write_console(console, "0"); + return; + } + + while value > 0 && len < digits.len() { + digits[len] = b'0' + (value % 10) as u8; + value /= 10; + len += 1; + } + + let mut output = [0u8; 20]; + for index in 0..len { + output[index] = digits[len - index - 1]; + } + let text = core::str::from_utf8(&output[..len]).unwrap_or("?"); + write_console(console, text); +} + #[cfg(target_os = "uefi")] #[panic_handler] fn panic(_info: &PanicInfo<'_>) -> ! { From 50d7390fa712b7e7827dfc1640b9580512291ff1 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 11 May 2026 08:14:15 +0000 Subject: [PATCH 08/39] feat: probe EFI HTTP child handle creation and destruction --- httpboot-loader/src/lib.rs | 9 +- httpboot-loader/src/main.rs | 170 +++++++++++++++++++++++++++++++++++- 2 files changed, 174 insertions(+), 5 deletions(-) diff --git a/httpboot-loader/src/lib.rs b/httpboot-loader/src/lib.rs index 1accfb2d..42a521ed 100644 --- a/httpboot-loader/src/lib.rs +++ b/httpboot-loader/src/lib.rs @@ -237,7 +237,8 @@ extern crate std; mod tests { use super::{ BootManifest, DownloadError, ManifestError, UrlError, parse_addr, - parse_downloaded_manifest, parse_manifest, uri_from_device_path, write_sibling_manifest_url, + parse_downloaded_manifest, parse_manifest, uri_from_device_path, + write_sibling_manifest_url, }; #[test] @@ -338,9 +339,9 @@ mod tests { fn wraps_downloaded_manifest_parse_errors() { assert_eq!( parse_downloaded_manifest(br#"{"kernel_size":1}"#, 1024), - Err(DownloadError::InvalidManifest( - ManifestError::MissingField("kernel_url") - )) + Err(DownloadError::InvalidManifest(ManifestError::MissingField( + "kernel_url" + ))) ); } diff --git a/httpboot-loader/src/main.rs b/httpboot-loader/src/main.rs index 1a4a77f7..2fc1093b 100644 --- a/httpboot-loader/src/main.rs +++ b/httpboot-loader/src/main.rs @@ -147,6 +147,30 @@ struct EfiLoadedImageProtocol { file_path: *const EfiDevicePathProtocol, } +#[cfg(target_os = "uefi")] +#[repr(C)] +struct EfiServiceBindingProtocol { + create_child: extern "efiapi" fn( + this: *mut EfiServiceBindingProtocol, + child_handle: *mut EfiHandle, + ) -> EfiStatus, + destroy_child: extern "efiapi" fn( + this: *mut EfiServiceBindingProtocol, + child_handle: EfiHandle, + ) -> EfiStatus, +} + +#[cfg(target_os = "uefi")] +#[repr(C)] +struct EfiHttpProtocol { + get_mode_data: usize, + configure: usize, + request: usize, + cancel: usize, + response: usize, + poll: usize, +} + #[cfg(target_os = "uefi")] type EfiLocateSearchType = u32; #[cfg(target_os = "uefi")] @@ -246,7 +270,10 @@ fn print_http_protocol_probe( write_usize(console, count); write_console(console, "\r\n"); } - Err(_) => write_console(console, "failed to locate HTTP Service Binding Protocol\r\n"), + Err(_) => write_console( + console, + "failed to locate HTTP Service Binding Protocol\r\n", + ), } match count_protocol_handles(boot_services, &EFI_HTTP_PROTOCOL_GUID) { @@ -257,6 +284,8 @@ fn print_http_protocol_probe( } Err(_) => write_console(console, "failed to locate HTTP Protocol\r\n"), } + + probe_http_child(console, boot_services); } #[cfg(target_os = "uefi")] @@ -291,6 +320,111 @@ fn count_protocol_handles( Ok(handle_count) } +#[cfg(target_os = "uefi")] +fn first_protocol_handle( + boot_services: &mut EfiBootServices, + protocol: &EfiGuid, +) -> Result { + let mut handle_count = 0usize; + let mut handles = core::ptr::null_mut(); + let status = (boot_services.locate_handle_buffer)( + EFI_LOCATE_BY_PROTOCOL, + protocol, + core::ptr::null_mut(), + &mut handle_count, + &mut handles, + ); + if status.is_error() { + return Err(status); + } + + let first = if handle_count > 0 && !handles.is_null() { + Some(unsafe { *handles }) + } else { + None + }; + if !handles.is_null() { + let _ = (boot_services.free_pool)(handles as *mut c_void); + } + first.ok_or(EFI_UNSUPPORTED) +} + +#[cfg(target_os = "uefi")] +fn open_protocol_on_handle( + boot_services: &mut EfiBootServices, + handle: EfiHandle, + protocol: &EfiGuid, +) -> Result<*mut T, EfiStatus> { + let mut interface = core::ptr::null_mut(); + let status = (boot_services.handle_protocol)(handle, protocol, &mut interface); + if status.is_error() || interface.is_null() { + return Err(status); + } + Ok(interface as *mut T) +} + +#[cfg(target_os = "uefi")] +fn probe_http_child( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, +) { + let service_handle = + match first_protocol_handle(boot_services, &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID) { + Ok(handle) => handle, + Err(status) => { + write_console( + console, + "http_create_child_skipped: service binding not found ", + ); + write_status(console, status); + write_console(console, "\r\n"); + return; + } + }; + + let service_binding = match open_protocol_on_handle::( + boot_services, + service_handle, + &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, + ) { + Ok(service_binding) => service_binding, + Err(status) => { + write_console(console, "http_service_binding_open_failed: "); + write_status(console, status); + write_console(console, "\r\n"); + return; + } + }; + + let mut child_handle = core::ptr::null_mut(); + let create_status = + unsafe { ((*service_binding).create_child)(service_binding, &mut child_handle) }; + write_console(console, "http_create_child_status: "); + write_status(console, create_status); + write_console(console, "\r\n"); + if create_status.is_error() || child_handle.is_null() { + return; + } + + let http_status = match open_protocol_on_handle::( + boot_services, + child_handle, + &EFI_HTTP_PROTOCOL_GUID, + ) { + Ok(_) => EFI_SUCCESS, + Err(status) => status, + }; + write_console(console, "http_child_protocol_status: "); + write_status(console, http_status); + write_console(console, "\r\n"); + + let destroy_status = + unsafe { ((*service_binding).destroy_child)(service_binding, child_handle) }; + write_console(console, "http_destroy_child_status: "); + write_status(console, destroy_status); + write_console(console, "\r\n"); +} + #[cfg(target_os = "uefi")] fn loader_url_from_loaded_image<'a>( image: EfiHandle, @@ -403,6 +537,40 @@ fn write_usize(console: *mut EfiSimpleTextOutputProtocol, mut value: usize) { write_console(console, text); } +#[cfg(target_os = "uefi")] +fn write_status(console: *mut EfiSimpleTextOutputProtocol, status: EfiStatus) { + write_console(console, "0x"); + write_hex_usize(console, status.0); +} + +#[cfg(target_os = "uefi")] +fn write_hex_usize(console: *mut EfiSimpleTextOutputProtocol, mut value: usize) { + let mut digits = [0u8; 16]; + let mut len = 0; + + if value == 0 { + write_console(console, "0"); + return; + } + + while value > 0 && len < digits.len() { + let digit = (value & 0xf) as u8; + digits[len] = match digit { + 0..=9 => b'0' + digit, + _ => b'a' + (digit - 10), + }; + value >>= 4; + len += 1; + } + + let mut output = [0u8; 16]; + for index in 0..len { + output[index] = digits[len - index - 1]; + } + let text = core::str::from_utf8(&output[..len]).unwrap_or("?"); + write_console(console, text); +} + #[cfg(target_os = "uefi")] #[panic_handler] fn panic(_info: &PanicInfo<'_>) -> ! { From b54cfed54e4fd9dca6c7a7094e48aab8146afd2c Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 11 May 2026 08:18:33 +0000 Subject: [PATCH 09/39] feat: probe EFI HTTP configure and reset with IPv4 default settings --- httpboot-loader/src/main.rs | 93 ++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 6 deletions(-) diff --git a/httpboot-loader/src/main.rs b/httpboot-loader/src/main.rs index 2fc1093b..4e450e6c 100644 --- a/httpboot-loader/src/main.rs +++ b/httpboot-loader/src/main.rs @@ -164,13 +164,45 @@ struct EfiServiceBindingProtocol { #[repr(C)] struct EfiHttpProtocol { get_mode_data: usize, - configure: usize, + configure: extern "efiapi" fn( + this: *mut EfiHttpProtocol, + http_config_data: *mut EfiHttpConfigData, + ) -> EfiStatus, request: usize, cancel: usize, response: usize, poll: usize, } +#[cfg(target_os = "uefi")] +#[repr(C)] +struct EfiHttpConfigData { + http_version: u32, + timeout_millisec: u32, + local_address_is_ipv6: u8, + _padding: [u8; 7], + access_point: EfiHttpConfigAccessPoint, +} + +#[cfg(target_os = "uefi")] +#[repr(C)] +union EfiHttpConfigAccessPoint { + ipv4_node: *mut EfiHttpv4AccessPoint, + ipv6_node: *mut c_void, +} + +#[cfg(target_os = "uefi")] +#[repr(C)] +struct EfiHttpv4AccessPoint { + use_default_address: u8, + local_address: [u8; 4], + local_subnet: [u8; 4], + local_port: u16, +} + +#[cfg(target_os = "uefi")] +const HTTP_VERSION_11: u32 = 1; + #[cfg(target_os = "uefi")] type EfiLocateSearchType = u32; #[cfg(target_os = "uefi")] @@ -406,18 +438,67 @@ fn probe_http_child( return; } - let http_status = match open_protocol_on_handle::( + let http_protocol = match open_protocol_on_handle::( boot_services, child_handle, &EFI_HTTP_PROTOCOL_GUID, ) { - Ok(_) => EFI_SUCCESS, - Err(status) => status, + Ok(http_protocol) => { + write_console(console, "http_child_protocol_status: 0x0\r\n"); + http_protocol + } + Err(status) => { + write_console(console, "http_child_protocol_status: "); + write_status(console, status); + write_console(console, "\r\n"); + destroy_http_child(console, service_binding, child_handle); + return; + } }; - write_console(console, "http_child_protocol_status: "); - write_status(console, http_status); + + let configure_status = configure_http_ipv4_default(http_protocol); + write_console(console, "http_configure_status: "); + write_status(console, configure_status); write_console(console, "\r\n"); + if !configure_status.is_error() { + let reset_status = + unsafe { ((*http_protocol).configure)(http_protocol, core::ptr::null_mut()) }; + write_console(console, "http_reset_status: "); + write_status(console, reset_status); + write_console(console, "\r\n"); + } + + destroy_http_child(console, service_binding, child_handle); +} + +#[cfg(target_os = "uefi")] +fn configure_http_ipv4_default(http_protocol: *mut EfiHttpProtocol) -> EfiStatus { + let mut ipv4 = EfiHttpv4AccessPoint { + use_default_address: 1, + local_address: [0; 4], + local_subnet: [0; 4], + local_port: 0, + }; + let mut config = EfiHttpConfigData { + http_version: HTTP_VERSION_11, + timeout_millisec: 10_000, + local_address_is_ipv6: 0, + _padding: [0; 7], + access_point: EfiHttpConfigAccessPoint { + ipv4_node: &mut ipv4, + }, + }; + + unsafe { ((*http_protocol).configure)(http_protocol, &mut config) } +} + +#[cfg(target_os = "uefi")] +fn destroy_http_child( + console: *mut EfiSimpleTextOutputProtocol, + service_binding: *mut EfiServiceBindingProtocol, + child_handle: EfiHandle, +) { let destroy_status = unsafe { ((*service_binding).destroy_child)(service_binding, child_handle) }; write_console(console, "http_destroy_child_status: "); From 3b4260cccc77eb107ddf25a7bbf340828441b1ab Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 11 May 2026 08:32:20 +0000 Subject: [PATCH 10/39] feat: refactor UEFI types into modules and implement HTTP GET request for manifest --- httpboot-loader/src/main.rs | 594 +---------------------- httpboot-loader/src/uefi/abi.rs | 247 ++++++++++ httpboot-loader/src/uefi/console.rs | 88 ++++ httpboot-loader/src/uefi/http.rs | 304 ++++++++++++ httpboot-loader/src/uefi/loaded_image.rs | 73 +++ httpboot-loader/src/uefi/mod.rs | 4 + 6 files changed, 728 insertions(+), 582 deletions(-) create mode 100644 httpboot-loader/src/uefi/abi.rs create mode 100644 httpboot-loader/src/uefi/console.rs create mode 100644 httpboot-loader/src/uefi/http.rs create mode 100644 httpboot-loader/src/uefi/loaded_image.rs create mode 100644 httpboot-loader/src/uefi/mod.rs diff --git a/httpboot-loader/src/main.rs b/httpboot-loader/src/main.rs index 4e450e6c..cc0fe3a2 100644 --- a/httpboot-loader/src/main.rs +++ b/httpboot-loader/src/main.rs @@ -5,225 +5,28 @@ compile_error!("the uefi-app feature must be built with a *-unknown-uefi target"); #[cfg(target_os = "uefi")] -use core::{ffi::c_void, panic::PanicInfo}; +use core::panic::PanicInfo; #[cfg(target_os = "uefi")] -use httpboot_loader::{uri_from_device_path, write_sibling_manifest_url}; +use httpboot_loader::write_sibling_manifest_url; #[cfg(target_os = "uefi")] -type EfiHandle = *mut c_void; +mod uefi; #[cfg(target_os = "uefi")] -#[repr(transparent)] -#[derive(Clone, Copy, PartialEq, Eq)] -pub struct EfiStatus(usize); - -#[cfg(target_os = "uefi")] -const EFI_SUCCESS: EfiStatus = EfiStatus(0); -#[cfg(target_os = "uefi")] -const EFI_UNSUPPORTED: EfiStatus = EfiStatus(3); +use uefi::abi::{EFI_SUCCESS, EFI_UNSUPPORTED, EfiHandle, EfiStatus, EfiSystemTable}; #[cfg(target_os = "uefi")] -const EFI_LOADED_IMAGE_PROTOCOL_GUID: EfiGuid = EfiGuid { - data1: 0x5b1b31a1, - data2: 0x9562, - data3: 0x11d2, - data4: [0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], -}; +use uefi::console::write_console; #[cfg(target_os = "uefi")] -const EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { - data1: 0xbdc8e6af, - data2: 0xd9bc, - data3: 0x4379, - data4: [0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c], -}; +use uefi::http::print_http_protocol_probe; #[cfg(target_os = "uefi")] -const EFI_HTTP_PROTOCOL_GUID: EfiGuid = EfiGuid { - data1: 0x7a59b29b, - data2: 0x910b, - data3: 0x4171, - data4: [0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b], -}; +use uefi::loaded_image::{LoaderError, loader_url_from_loaded_image}; #[cfg(target_os = "uefi")] const DEVICE_PATH_BUFFER_SIZE: usize = 1024; #[cfg(target_os = "uefi")] const URL_BUFFER_SIZE: usize = 1024; -#[cfg(target_os = "uefi")] -#[repr(C)] -struct EfiGuid { - data1: u32, - data2: u16, - data3: u16, - data4: [u8; 8], -} - -#[cfg(target_os = "uefi")] -#[repr(C)] -struct EfiTableHeader { - signature: u64, - revision: u32, - header_size: u32, - crc32: u32, - reserved: u32, -} - -#[cfg(target_os = "uefi")] -#[repr(C)] -struct EfiSimpleTextOutputProtocol { - reset: usize, - output_string: - extern "efiapi" fn(this: *mut EfiSimpleTextOutputProtocol, string: *const u16) -> EfiStatus, -} - -#[cfg(target_os = "uefi")] -#[repr(C)] -struct EfiBootServices { - hdr: EfiTableHeader, - _raise_tpl: usize, - _restore_tpl: usize, - _allocate_pages: usize, - _free_pages: usize, - _get_memory_map: usize, - _allocate_pool: usize, - free_pool: extern "efiapi" fn(buffer: *mut c_void) -> EfiStatus, - _create_event: usize, - _set_timer: usize, - _wait_for_event: usize, - _signal_event: usize, - _close_event: usize, - _check_event: usize, - _install_protocol_interface: usize, - _reinstall_protocol_interface: usize, - _uninstall_protocol_interface: usize, - handle_protocol: extern "efiapi" fn( - handle: EfiHandle, - protocol: *const EfiGuid, - interface: *mut *mut c_void, - ) -> EfiStatus, - _reserved: usize, - _register_protocol_notify: usize, - _locate_handle: usize, - _locate_device_path: usize, - _install_configuration_table: usize, - _load_image: usize, - _start_image: usize, - _exit: usize, - _unload_image: usize, - _exit_boot_services: usize, - _get_next_monotonic_count: usize, - _stall: usize, - _set_watchdog_timer: usize, - _connect_controller: usize, - _disconnect_controller: usize, - _open_protocol: usize, - _close_protocol: usize, - _open_protocol_information: usize, - _protocols_per_handle: usize, - locate_handle_buffer: extern "efiapi" fn( - search_type: EfiLocateSearchType, - protocol: *const EfiGuid, - search_key: *mut c_void, - no_handles: *mut usize, - buffer: *mut *mut EfiHandle, - ) -> EfiStatus, -} - -#[cfg(target_os = "uefi")] -#[repr(C)] -struct EfiDevicePathProtocol { - node_type: u8, - node_subtype: u8, - length: [u8; 2], -} - -#[cfg(target_os = "uefi")] -#[repr(C)] -struct EfiLoadedImageProtocol { - revision: u32, - parent_handle: EfiHandle, - system_table: *mut EfiSystemTable, - device_handle: EfiHandle, - file_path: *const EfiDevicePathProtocol, -} - -#[cfg(target_os = "uefi")] -#[repr(C)] -struct EfiServiceBindingProtocol { - create_child: extern "efiapi" fn( - this: *mut EfiServiceBindingProtocol, - child_handle: *mut EfiHandle, - ) -> EfiStatus, - destroy_child: extern "efiapi" fn( - this: *mut EfiServiceBindingProtocol, - child_handle: EfiHandle, - ) -> EfiStatus, -} - -#[cfg(target_os = "uefi")] -#[repr(C)] -struct EfiHttpProtocol { - get_mode_data: usize, - configure: extern "efiapi" fn( - this: *mut EfiHttpProtocol, - http_config_data: *mut EfiHttpConfigData, - ) -> EfiStatus, - request: usize, - cancel: usize, - response: usize, - poll: usize, -} - -#[cfg(target_os = "uefi")] -#[repr(C)] -struct EfiHttpConfigData { - http_version: u32, - timeout_millisec: u32, - local_address_is_ipv6: u8, - _padding: [u8; 7], - access_point: EfiHttpConfigAccessPoint, -} - -#[cfg(target_os = "uefi")] -#[repr(C)] -union EfiHttpConfigAccessPoint { - ipv4_node: *mut EfiHttpv4AccessPoint, - ipv6_node: *mut c_void, -} - -#[cfg(target_os = "uefi")] -#[repr(C)] -struct EfiHttpv4AccessPoint { - use_default_address: u8, - local_address: [u8; 4], - local_subnet: [u8; 4], - local_port: u16, -} - -#[cfg(target_os = "uefi")] -const HTTP_VERSION_11: u32 = 1; - -#[cfg(target_os = "uefi")] -type EfiLocateSearchType = u32; -#[cfg(target_os = "uefi")] -const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; - -#[cfg(target_os = "uefi")] -#[repr(C)] -pub struct EfiSystemTable { - hdr: EfiTableHeader, - firmware_vendor: *mut u16, - firmware_revision: u32, - console_in_handle: EfiHandle, - con_in: *mut c_void, - console_out_handle: EfiHandle, - con_out: *mut EfiSimpleTextOutputProtocol, - standard_error_handle: EfiHandle, - std_err: *mut EfiSimpleTextOutputProtocol, - runtime_services: *mut c_void, - boot_services: *mut EfiBootServices, -} - #[cfg(target_os = "uefi")] #[unsafe(no_mangle)] pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTable) -> EfiStatus { @@ -239,6 +42,7 @@ pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTa let mut device_path_buffer = [0u8; DEVICE_PATH_BUFFER_SIZE]; let mut manifest_url_buffer = [0u8; URL_BUFFER_SIZE]; + let mut manifest_url = None; match loader_url_from_loaded_image(image, system_table, &mut device_path_buffer) { Ok(loader_url) => { write_console(console, "loader_url: "); @@ -246,10 +50,11 @@ pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTa write_console(console, "\r\n"); match write_sibling_manifest_url(loader_url, &mut manifest_url_buffer) { - Ok(manifest_url) => { + Ok(manifest_url_text) => { write_console(console, "manifest_url: "); - write_console(console, manifest_url); + write_console(console, manifest_url_text); write_console(console, "\r\n"); + manifest_url = Some(manifest_url_text); } Err(_) => write_console(console, "failed to build manifest URL\r\n"), } @@ -272,386 +77,11 @@ pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTa console, "HTTP download backend is pending; manifest bytes parser linked\r\n", ); - print_http_protocol_probe(console, system_table); + print_http_protocol_probe(console, system_table, manifest_url); EFI_SUCCESS } -#[cfg(target_os = "uefi")] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -enum LoaderError { - ProtocolUnavailable, - MissingFilePath, - DevicePathTooLarge, - InvalidDevicePath, -} - -#[cfg(target_os = "uefi")] -fn print_http_protocol_probe( - console: *mut EfiSimpleTextOutputProtocol, - system_table: *mut EfiSystemTable, -) { - let Some(boot_services) = boot_services_from_system_table(system_table) else { - write_console(console, "failed to access Boot Services for HTTP probe\r\n"); - return; - }; - - match count_protocol_handles(boot_services, &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID) { - Ok(count) => { - write_console(console, "http_service_binding_handles: "); - write_usize(console, count); - write_console(console, "\r\n"); - } - Err(_) => write_console( - console, - "failed to locate HTTP Service Binding Protocol\r\n", - ), - } - - match count_protocol_handles(boot_services, &EFI_HTTP_PROTOCOL_GUID) { - Ok(count) => { - write_console(console, "http_protocol_handles: "); - write_usize(console, count); - write_console(console, "\r\n"); - } - Err(_) => write_console(console, "failed to locate HTTP Protocol\r\n"), - } - - probe_http_child(console, boot_services); -} - -#[cfg(target_os = "uefi")] -fn boot_services_from_system_table( - system_table: *mut EfiSystemTable, -) -> Option<&'static mut EfiBootServices> { - (unsafe { system_table.as_mut() }) - .map(|table| table.boot_services) - .and_then(|boot_services| unsafe { boot_services.as_mut() }) -} - -#[cfg(target_os = "uefi")] -fn count_protocol_handles( - boot_services: &mut EfiBootServices, - protocol: &EfiGuid, -) -> Result { - let mut handle_count = 0usize; - let mut handles = core::ptr::null_mut(); - let status = (boot_services.locate_handle_buffer)( - EFI_LOCATE_BY_PROTOCOL, - protocol, - core::ptr::null_mut(), - &mut handle_count, - &mut handles, - ); - if status.is_error() { - return Err(status); - } - if !handles.is_null() { - let _ = (boot_services.free_pool)(handles as *mut c_void); - } - Ok(handle_count) -} - -#[cfg(target_os = "uefi")] -fn first_protocol_handle( - boot_services: &mut EfiBootServices, - protocol: &EfiGuid, -) -> Result { - let mut handle_count = 0usize; - let mut handles = core::ptr::null_mut(); - let status = (boot_services.locate_handle_buffer)( - EFI_LOCATE_BY_PROTOCOL, - protocol, - core::ptr::null_mut(), - &mut handle_count, - &mut handles, - ); - if status.is_error() { - return Err(status); - } - - let first = if handle_count > 0 && !handles.is_null() { - Some(unsafe { *handles }) - } else { - None - }; - if !handles.is_null() { - let _ = (boot_services.free_pool)(handles as *mut c_void); - } - first.ok_or(EFI_UNSUPPORTED) -} - -#[cfg(target_os = "uefi")] -fn open_protocol_on_handle( - boot_services: &mut EfiBootServices, - handle: EfiHandle, - protocol: &EfiGuid, -) -> Result<*mut T, EfiStatus> { - let mut interface = core::ptr::null_mut(); - let status = (boot_services.handle_protocol)(handle, protocol, &mut interface); - if status.is_error() || interface.is_null() { - return Err(status); - } - Ok(interface as *mut T) -} - -#[cfg(target_os = "uefi")] -fn probe_http_child( - console: *mut EfiSimpleTextOutputProtocol, - boot_services: &mut EfiBootServices, -) { - let service_handle = - match first_protocol_handle(boot_services, &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID) { - Ok(handle) => handle, - Err(status) => { - write_console( - console, - "http_create_child_skipped: service binding not found ", - ); - write_status(console, status); - write_console(console, "\r\n"); - return; - } - }; - - let service_binding = match open_protocol_on_handle::( - boot_services, - service_handle, - &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, - ) { - Ok(service_binding) => service_binding, - Err(status) => { - write_console(console, "http_service_binding_open_failed: "); - write_status(console, status); - write_console(console, "\r\n"); - return; - } - }; - - let mut child_handle = core::ptr::null_mut(); - let create_status = - unsafe { ((*service_binding).create_child)(service_binding, &mut child_handle) }; - write_console(console, "http_create_child_status: "); - write_status(console, create_status); - write_console(console, "\r\n"); - if create_status.is_error() || child_handle.is_null() { - return; - } - - let http_protocol = match open_protocol_on_handle::( - boot_services, - child_handle, - &EFI_HTTP_PROTOCOL_GUID, - ) { - Ok(http_protocol) => { - write_console(console, "http_child_protocol_status: 0x0\r\n"); - http_protocol - } - Err(status) => { - write_console(console, "http_child_protocol_status: "); - write_status(console, status); - write_console(console, "\r\n"); - destroy_http_child(console, service_binding, child_handle); - return; - } - }; - - let configure_status = configure_http_ipv4_default(http_protocol); - write_console(console, "http_configure_status: "); - write_status(console, configure_status); - write_console(console, "\r\n"); - - if !configure_status.is_error() { - let reset_status = - unsafe { ((*http_protocol).configure)(http_protocol, core::ptr::null_mut()) }; - write_console(console, "http_reset_status: "); - write_status(console, reset_status); - write_console(console, "\r\n"); - } - - destroy_http_child(console, service_binding, child_handle); -} - -#[cfg(target_os = "uefi")] -fn configure_http_ipv4_default(http_protocol: *mut EfiHttpProtocol) -> EfiStatus { - let mut ipv4 = EfiHttpv4AccessPoint { - use_default_address: 1, - local_address: [0; 4], - local_subnet: [0; 4], - local_port: 0, - }; - let mut config = EfiHttpConfigData { - http_version: HTTP_VERSION_11, - timeout_millisec: 10_000, - local_address_is_ipv6: 0, - _padding: [0; 7], - access_point: EfiHttpConfigAccessPoint { - ipv4_node: &mut ipv4, - }, - }; - - unsafe { ((*http_protocol).configure)(http_protocol, &mut config) } -} - -#[cfg(target_os = "uefi")] -fn destroy_http_child( - console: *mut EfiSimpleTextOutputProtocol, - service_binding: *mut EfiServiceBindingProtocol, - child_handle: EfiHandle, -) { - let destroy_status = - unsafe { ((*service_binding).destroy_child)(service_binding, child_handle) }; - write_console(console, "http_destroy_child_status: "); - write_status(console, destroy_status); - write_console(console, "\r\n"); -} - -#[cfg(target_os = "uefi")] -fn loader_url_from_loaded_image<'a>( - image: EfiHandle, - system_table: *mut EfiSystemTable, - buffer: &'a mut [u8], -) -> Result<&'a str, LoaderError> { - let boot_services = - boot_services_from_system_table(system_table).ok_or(LoaderError::ProtocolUnavailable)?; - - let mut interface = core::ptr::null_mut(); - let status = - (boot_services.handle_protocol)(image, &EFI_LOADED_IMAGE_PROTOCOL_GUID, &mut interface); - if status.is_error() || interface.is_null() { - return Err(LoaderError::ProtocolUnavailable); - } - - let loaded_image = unsafe { (interface as *mut EfiLoadedImageProtocol).as_ref() } - .ok_or(LoaderError::ProtocolUnavailable)?; - if loaded_image.file_path.is_null() { - return Err(LoaderError::MissingFilePath); - } - - let size = copy_device_path_to_buffer(loaded_image.file_path, buffer)?; - uri_from_device_path(&buffer[..size]).map_err(|_| LoaderError::InvalidDevicePath) -} - -#[cfg(target_os = "uefi")] -fn copy_device_path_to_buffer( - device_path: *const EfiDevicePathProtocol, - buffer: &mut [u8], -) -> Result { - let mut offset = 0; - let mut current = device_path; - - loop { - let node = unsafe { current.as_ref() }.ok_or(LoaderError::MissingFilePath)?; - let node_len = u16::from_le_bytes(node.length) as usize; - if node_len < 4 { - return Err(LoaderError::InvalidDevicePath); - } - if offset + node_len > buffer.len() { - return Err(LoaderError::DevicePathTooLarge); - } - - unsafe { - core::ptr::copy_nonoverlapping( - current as *const u8, - buffer.as_mut_ptr().add(offset), - node_len, - ); - } - offset += node_len; - - if node.node_type == 0x7f && node.node_subtype == 0xff { - return Ok(offset); - } - - current = unsafe { (current as *const u8).add(node_len) as *const EfiDevicePathProtocol }; - } -} - -#[cfg(target_os = "uefi")] -impl EfiStatus { - fn is_error(self) -> bool { - self.0 & (1usize << (usize::BITS - 1)) != 0 - } -} - -#[cfg(target_os = "uefi")] -fn write_console(console: *mut EfiSimpleTextOutputProtocol, message: &str) { - let Some(console_ref) = (unsafe { console.as_mut() }) else { - return; - }; - - let mut buffer = [0u16; 192]; - let mut index = 0; - for unit in message.encode_utf16() { - if index + 1 >= buffer.len() { - break; - } - buffer[index] = unit; - index += 1; - } - buffer[index] = 0; - - (console_ref.output_string)(console, buffer.as_ptr()); -} - -#[cfg(target_os = "uefi")] -fn write_usize(console: *mut EfiSimpleTextOutputProtocol, mut value: usize) { - let mut digits = [0u8; 20]; - let mut len = 0; - - if value == 0 { - write_console(console, "0"); - return; - } - - while value > 0 && len < digits.len() { - digits[len] = b'0' + (value % 10) as u8; - value /= 10; - len += 1; - } - - let mut output = [0u8; 20]; - for index in 0..len { - output[index] = digits[len - index - 1]; - } - let text = core::str::from_utf8(&output[..len]).unwrap_or("?"); - write_console(console, text); -} - -#[cfg(target_os = "uefi")] -fn write_status(console: *mut EfiSimpleTextOutputProtocol, status: EfiStatus) { - write_console(console, "0x"); - write_hex_usize(console, status.0); -} - -#[cfg(target_os = "uefi")] -fn write_hex_usize(console: *mut EfiSimpleTextOutputProtocol, mut value: usize) { - let mut digits = [0u8; 16]; - let mut len = 0; - - if value == 0 { - write_console(console, "0"); - return; - } - - while value > 0 && len < digits.len() { - let digit = (value & 0xf) as u8; - digits[len] = match digit { - 0..=9 => b'0' + digit, - _ => b'a' + (digit - 10), - }; - value >>= 4; - len += 1; - } - - let mut output = [0u8; 16]; - for index in 0..len { - output[index] = digits[len - index - 1]; - } - let text = core::str::from_utf8(&output[..len]).unwrap_or("?"); - write_console(console, text); -} - #[cfg(target_os = "uefi")] #[panic_handler] fn panic(_info: &PanicInfo<'_>) -> ! { diff --git a/httpboot-loader/src/uefi/abi.rs b/httpboot-loader/src/uefi/abi.rs new file mode 100644 index 00000000..40dcc0a1 --- /dev/null +++ b/httpboot-loader/src/uefi/abi.rs @@ -0,0 +1,247 @@ +use core::ffi::c_void; + +pub type EfiHandle = *mut c_void; +pub type EfiEvent = *mut c_void; +pub type EfiLocateSearchType = u32; +pub type EfiEventNotify = Option; + +pub const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; + +#[repr(transparent)] +#[derive(Clone, Copy, PartialEq, Eq)] +pub struct EfiStatus(pub usize); + +pub const EFI_SUCCESS: EfiStatus = EfiStatus(0); +pub const EFI_ERROR_BIT: usize = 1usize << (usize::BITS - 1); +pub const EFI_UNSUPPORTED: EfiStatus = EfiStatus(EFI_ERROR_BIT | 3); +pub const EFI_NOT_READY: EfiStatus = EfiStatus(EFI_ERROR_BIT | 6); + +pub const EFI_LOADED_IMAGE_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x5b1b31a1, + data2: 0x9562, + data3: 0x11d2, + data4: [0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b], +}; + +pub const EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0xbdc8e6af, + data2: 0xd9bc, + data3: 0x4379, + data4: [0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c], +}; + +pub const EFI_HTTP_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x7a59b29b, + data2: 0x910b, + data3: 0x4171, + data4: [0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b], +}; + +pub const EVT_NOTIFY_SIGNAL: u32 = 0x0000_0200; +pub const TPL_CALLBACK: usize = 8; +pub const HTTP_VERSION_11: u32 = 1; +pub const HTTP_METHOD_GET: u32 = 0; + +#[repr(C)] +pub struct EfiGuid { + pub data1: u32, + pub data2: u16, + pub data3: u16, + pub data4: [u8; 8], +} + +#[repr(C)] +pub struct EfiTableHeader { + signature: u64, + revision: u32, + header_size: u32, + crc32: u32, + reserved: u32, +} + +#[repr(C)] +pub struct EfiSimpleTextOutputProtocol { + pub reset: usize, + pub output_string: + extern "efiapi" fn(this: *mut EfiSimpleTextOutputProtocol, string: *const u16) -> EfiStatus, +} + +#[repr(C)] +pub struct EfiBootServices { + pub hdr: EfiTableHeader, + pub _raise_tpl: usize, + pub _restore_tpl: usize, + pub _allocate_pages: usize, + pub _free_pages: usize, + pub _get_memory_map: usize, + pub _allocate_pool: usize, + pub free_pool: extern "efiapi" fn(buffer: *mut c_void) -> EfiStatus, + pub create_event: extern "efiapi" fn( + event_type: u32, + notify_tpl: usize, + notify_function: EfiEventNotify, + notify_context: *mut c_void, + event: *mut EfiEvent, + ) -> EfiStatus, + pub _set_timer: usize, + pub _wait_for_event: usize, + pub _signal_event: usize, + pub close_event: extern "efiapi" fn(event: EfiEvent) -> EfiStatus, + pub _check_event: usize, + pub _install_protocol_interface: usize, + pub _reinstall_protocol_interface: usize, + pub _uninstall_protocol_interface: usize, + pub handle_protocol: extern "efiapi" fn( + handle: EfiHandle, + protocol: *const EfiGuid, + interface: *mut *mut c_void, + ) -> EfiStatus, + pub _reserved: usize, + pub _register_protocol_notify: usize, + pub _locate_handle: usize, + pub _locate_device_path: usize, + pub _install_configuration_table: usize, + pub _load_image: usize, + pub _start_image: usize, + pub _exit: usize, + pub _unload_image: usize, + pub _exit_boot_services: usize, + pub _get_next_monotonic_count: usize, + pub _stall: usize, + pub _set_watchdog_timer: usize, + pub _connect_controller: usize, + pub _disconnect_controller: usize, + pub _open_protocol: usize, + pub _close_protocol: usize, + pub _open_protocol_information: usize, + pub _protocols_per_handle: usize, + pub locate_handle_buffer: extern "efiapi" fn( + search_type: EfiLocateSearchType, + protocol: *const EfiGuid, + search_key: *mut c_void, + no_handles: *mut usize, + buffer: *mut *mut EfiHandle, + ) -> EfiStatus, +} + +#[repr(C)] +pub struct EfiDevicePathProtocol { + pub node_type: u8, + pub node_subtype: u8, + pub length: [u8; 2], +} + +#[repr(C)] +pub struct EfiLoadedImageProtocol { + pub revision: u32, + pub parent_handle: EfiHandle, + pub system_table: *mut EfiSystemTable, + pub device_handle: EfiHandle, + pub file_path: *const EfiDevicePathProtocol, +} + +#[repr(C)] +pub struct EfiServiceBindingProtocol { + pub create_child: extern "efiapi" fn( + this: *mut EfiServiceBindingProtocol, + child_handle: *mut EfiHandle, + ) -> EfiStatus, + pub destroy_child: extern "efiapi" fn( + this: *mut EfiServiceBindingProtocol, + child_handle: EfiHandle, + ) -> EfiStatus, +} + +#[repr(C)] +pub struct EfiHttpProtocol { + pub get_mode_data: usize, + pub configure: extern "efiapi" fn( + this: *mut EfiHttpProtocol, + http_config_data: *mut EfiHttpConfigData, + ) -> EfiStatus, + pub request: + extern "efiapi" fn(this: *mut EfiHttpProtocol, token: *mut EfiHttpToken) -> EfiStatus, + pub cancel: usize, + pub response: usize, + pub poll: extern "efiapi" fn(this: *mut EfiHttpProtocol) -> EfiStatus, +} + +#[repr(C)] +pub struct EfiHttpConfigData { + pub http_version: u32, + pub timeout_millisec: u32, + pub local_address_is_ipv6: u8, + pub _padding: [u8; 7], + pub access_point: EfiHttpConfigAccessPoint, +} + +#[repr(C)] +pub union EfiHttpConfigAccessPoint { + pub ipv4_node: *mut EfiHttpv4AccessPoint, + pub ipv6_node: *mut c_void, +} + +#[repr(C)] +pub struct EfiHttpv4AccessPoint { + pub use_default_address: u8, + pub local_address: [u8; 4], + pub local_subnet: [u8; 4], + pub local_port: u16, +} + +#[repr(C)] +pub union EfiHttpMessageData { + pub request: *mut EfiHttpRequestData, + pub response: *mut c_void, +} + +#[repr(C)] +pub struct EfiHttpRequestData { + pub method: u32, + pub url: *mut u16, +} + +#[repr(C)] +pub struct EfiHttpMessage { + pub data: EfiHttpMessageData, + pub header_count: usize, + pub headers: *mut c_void, + pub body_length: usize, + pub body: *mut c_void, +} + +#[repr(C)] +pub struct EfiHttpToken { + pub event: EfiEvent, + pub status: EfiStatus, + pub message: *mut EfiHttpMessage, +} + +#[repr(C)] +pub struct EfiSystemTable { + pub hdr: EfiTableHeader, + pub firmware_vendor: *mut u16, + pub firmware_revision: u32, + pub console_in_handle: EfiHandle, + pub con_in: *mut c_void, + pub console_out_handle: EfiHandle, + pub con_out: *mut EfiSimpleTextOutputProtocol, + pub standard_error_handle: EfiHandle, + pub std_err: *mut EfiSimpleTextOutputProtocol, + pub runtime_services: *mut c_void, + pub boot_services: *mut EfiBootServices, +} + +impl EfiStatus { + pub fn is_error(self) -> bool { + self.0 & EFI_ERROR_BIT != 0 + } +} + +pub fn boot_services_from_system_table( + system_table: *mut EfiSystemTable, +) -> Option<&'static mut EfiBootServices> { + (unsafe { system_table.as_mut() }) + .map(|table| table.boot_services) + .and_then(|boot_services| unsafe { boot_services.as_mut() }) +} diff --git a/httpboot-loader/src/uefi/console.rs b/httpboot-loader/src/uefi/console.rs new file mode 100644 index 00000000..1dd604cc --- /dev/null +++ b/httpboot-loader/src/uefi/console.rs @@ -0,0 +1,88 @@ +use crate::uefi::abi::{EfiSimpleTextOutputProtocol, EfiStatus}; + +pub fn write_console(console: *mut EfiSimpleTextOutputProtocol, message: &str) { + let Some(console_ref) = (unsafe { console.as_mut() }) else { + return; + }; + + let mut buffer = [0u16; 192]; + let mut index = 0; + for unit in message.encode_utf16() { + if index + 1 >= buffer.len() { + break; + } + buffer[index] = unit; + index += 1; + } + buffer[index] = 0; + + (console_ref.output_string)(console, buffer.as_ptr()); +} + +pub fn write_usize(console: *mut EfiSimpleTextOutputProtocol, mut value: usize) { + let mut digits = [0u8; 20]; + let mut len = 0; + + if value == 0 { + write_console(console, "0"); + return; + } + + while value > 0 && len < digits.len() { + digits[len] = b'0' + (value % 10) as u8; + value /= 10; + len += 1; + } + + let mut output = [0u8; 20]; + for index in 0..len { + output[index] = digits[len - index - 1]; + } + let text = core::str::from_utf8(&output[..len]).unwrap_or("?"); + write_console(console, text); +} + +pub fn write_status(console: *mut EfiSimpleTextOutputProtocol, status: EfiStatus) { + write_console(console, "0x"); + write_hex_usize(console, status.0); +} + +pub fn write_utf16_nul<'a>(input: &str, output: &'a mut [u16]) -> Result<*mut u16, ()> { + let mut index = 0; + for unit in input.encode_utf16() { + if index + 1 >= output.len() { + return Err(()); + } + output[index] = unit; + index += 1; + } + output[index] = 0; + Ok(output.as_mut_ptr()) +} + +fn write_hex_usize(console: *mut EfiSimpleTextOutputProtocol, mut value: usize) { + let mut digits = [0u8; 16]; + let mut len = 0; + + if value == 0 { + write_console(console, "0"); + return; + } + + while value > 0 && len < digits.len() { + let digit = (value & 0xf) as u8; + digits[len] = match digit { + 0..=9 => b'0' + digit, + _ => b'a' + (digit - 10), + }; + value >>= 4; + len += 1; + } + + let mut output = [0u8; 16]; + for index in 0..len { + output[index] = digits[len - index - 1]; + } + let text = core::str::from_utf8(&output[..len]).unwrap_or("?"); + write_console(console, text); +} diff --git a/httpboot-loader/src/uefi/http.rs b/httpboot-loader/src/uefi/http.rs new file mode 100644 index 00000000..1ed067f6 --- /dev/null +++ b/httpboot-loader/src/uefi/http.rs @@ -0,0 +1,304 @@ +use core::ffi::c_void; + +use crate::uefi::abi::{ + EFI_HTTP_PROTOCOL_GUID, EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, EFI_LOCATE_BY_PROTOCOL, + EFI_NOT_READY, EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, EfiBootServices, EfiEvent, EfiGuid, + EfiHandle, EfiHttpConfigAccessPoint, EfiHttpConfigData, EfiHttpMessage, EfiHttpMessageData, + EfiHttpProtocol, EfiHttpRequestData, EfiHttpToken, EfiHttpv4AccessPoint, + EfiServiceBindingProtocol, EfiSimpleTextOutputProtocol, EfiStatus, EfiSystemTable, + HTTP_METHOD_GET, HTTP_VERSION_11, TPL_CALLBACK, boot_services_from_system_table, +}; +use crate::uefi::console::{write_console, write_status, write_usize, write_utf16_nul}; + +const UTF16_URL_BUFFER_SIZE: usize = 1024; +const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; + +pub fn print_http_protocol_probe( + console: *mut EfiSimpleTextOutputProtocol, + system_table: *mut EfiSystemTable, + manifest_url: Option<&str>, +) { + let Some(boot_services) = boot_services_from_system_table(system_table) else { + write_console(console, "failed to access Boot Services for HTTP probe\r\n"); + return; + }; + + match count_protocol_handles(boot_services, &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID) { + Ok(count) => { + write_console(console, "http_service_binding_handles: "); + write_usize(console, count); + write_console(console, "\r\n"); + } + Err(_) => write_console( + console, + "failed to locate HTTP Service Binding Protocol\r\n", + ), + } + + match count_protocol_handles(boot_services, &EFI_HTTP_PROTOCOL_GUID) { + Ok(count) => { + write_console(console, "http_protocol_handles: "); + write_usize(console, count); + write_console(console, "\r\n"); + } + Err(_) => write_console(console, "failed to locate HTTP Protocol\r\n"), + } + + probe_http_child(console, boot_services, manifest_url); +} + +fn count_protocol_handles( + boot_services: &mut EfiBootServices, + protocol: &EfiGuid, +) -> Result { + let mut handle_count = 0usize; + let mut handles = core::ptr::null_mut(); + let status = (boot_services.locate_handle_buffer)( + EFI_LOCATE_BY_PROTOCOL, + protocol, + core::ptr::null_mut(), + &mut handle_count, + &mut handles, + ); + if status.is_error() { + return Err(status); + } + if !handles.is_null() { + let _ = (boot_services.free_pool)(handles as *mut c_void); + } + Ok(handle_count) +} + +fn first_protocol_handle( + boot_services: &mut EfiBootServices, + protocol: &EfiGuid, +) -> Result { + let mut handle_count = 0usize; + let mut handles = core::ptr::null_mut(); + let status = (boot_services.locate_handle_buffer)( + EFI_LOCATE_BY_PROTOCOL, + protocol, + core::ptr::null_mut(), + &mut handle_count, + &mut handles, + ); + if status.is_error() { + return Err(status); + } + + let first = if handle_count > 0 && !handles.is_null() { + Some(unsafe { *handles }) + } else { + None + }; + if !handles.is_null() { + let _ = (boot_services.free_pool)(handles as *mut c_void); + } + first.ok_or(EFI_UNSUPPORTED) +} + +fn open_protocol_on_handle( + boot_services: &mut EfiBootServices, + handle: EfiHandle, + protocol: &EfiGuid, +) -> Result<*mut T, EfiStatus> { + let mut interface = core::ptr::null_mut(); + let status = (boot_services.handle_protocol)(handle, protocol, &mut interface); + if status.is_error() || interface.is_null() { + return Err(status); + } + Ok(interface as *mut T) +} + +fn probe_http_child( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + manifest_url: Option<&str>, +) { + let service_handle = + match first_protocol_handle(boot_services, &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID) { + Ok(handle) => handle, + Err(status) => { + write_console( + console, + "http_create_child_skipped: service binding not found ", + ); + write_status(console, status); + write_console(console, "\r\n"); + return; + } + }; + + let service_binding = match open_protocol_on_handle::( + boot_services, + service_handle, + &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, + ) { + Ok(service_binding) => service_binding, + Err(status) => { + write_console(console, "http_service_binding_open_failed: "); + write_status(console, status); + write_console(console, "\r\n"); + return; + } + }; + + let mut child_handle = core::ptr::null_mut(); + let create_status = + unsafe { ((*service_binding).create_child)(service_binding, &mut child_handle) }; + write_console(console, "http_create_child_status: "); + write_status(console, create_status); + write_console(console, "\r\n"); + if create_status.is_error() || child_handle.is_null() { + return; + } + + let http_protocol = match open_protocol_on_handle::( + boot_services, + child_handle, + &EFI_HTTP_PROTOCOL_GUID, + ) { + Ok(http_protocol) => { + write_console(console, "http_child_protocol_status: 0x0\r\n"); + http_protocol + } + Err(status) => { + write_console(console, "http_child_protocol_status: "); + write_status(console, status); + write_console(console, "\r\n"); + destroy_http_child(console, service_binding, child_handle); + return; + } + }; + + let configure_status = configure_http_ipv4_default(http_protocol); + write_console(console, "http_configure_status: "); + write_status(console, configure_status); + write_console(console, "\r\n"); + + if !configure_status.is_error() { + if let Some(manifest_url) = manifest_url { + let mut url_buffer = [0u16; UTF16_URL_BUFFER_SIZE]; + match write_utf16_nul(manifest_url, &mut url_buffer) { + Ok(url) => request_manifest(console, boot_services, http_protocol, url), + Err(_) => write_console(console, "http_request_skipped: URL too long\r\n"), + } + } else { + write_console( + console, + "http_request_skipped: manifest URL unavailable\r\n", + ); + } + + let reset_status = + unsafe { ((*http_protocol).configure)(http_protocol, core::ptr::null_mut()) }; + write_console(console, "http_reset_status: "); + write_status(console, reset_status); + write_console(console, "\r\n"); + } + + destroy_http_child(console, service_binding, child_handle); +} + +fn request_manifest( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + http_protocol: *mut EfiHttpProtocol, + url: *mut u16, +) { + let mut event = core::ptr::null_mut(); + let event_status = (boot_services.create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event_notify), + core::ptr::null_mut(), + &mut event, + ); + write_console(console, "http_request_event_status: "); + write_status(console, event_status); + write_console(console, "\r\n"); + if event_status.is_error() || event.is_null() { + return; + } + + let mut request_data = EfiHttpRequestData { + method: HTTP_METHOD_GET, + url, + }; + let mut message = EfiHttpMessage { + data: EfiHttpMessageData { + request: &mut request_data, + }, + header_count: 0, + headers: core::ptr::null_mut(), + body_length: 0, + body: core::ptr::null_mut(), + }; + let mut token = EfiHttpToken { + event, + status: EFI_NOT_READY, + message: &mut message, + }; + + let request_status = unsafe { ((*http_protocol).request)(http_protocol, &mut token) }; + write_console(console, "http_request_status: "); + write_status(console, request_status); + write_console(console, "\r\n"); + + if !request_status.is_error() { + let completion = poll_http_token(http_protocol, &token); + write_console(console, "http_request_completion: "); + write_status(console, completion); + write_console(console, "\r\n"); + } + + let close_status = (boot_services.close_event)(event); + write_console(console, "http_request_close_event_status: "); + write_status(console, close_status); + write_console(console, "\r\n"); +} + +extern "efiapi" fn noop_event_notify(_event: EfiEvent, _context: *mut c_void) {} + +fn poll_http_token(http_protocol: *mut EfiHttpProtocol, token: &EfiHttpToken) -> EfiStatus { + for _ in 0..HTTP_COMPLETION_POLL_LIMIT { + let status = unsafe { core::ptr::read_volatile(&token.status) }; + if status != EFI_NOT_READY { + return status; + } + let _ = unsafe { ((*http_protocol).poll)(http_protocol) }; + } + unsafe { core::ptr::read_volatile(&token.status) } +} + +fn configure_http_ipv4_default(http_protocol: *mut EfiHttpProtocol) -> EfiStatus { + let mut ipv4 = EfiHttpv4AccessPoint { + use_default_address: 1, + local_address: [0; 4], + local_subnet: [0; 4], + local_port: 0, + }; + let mut config = EfiHttpConfigData { + http_version: HTTP_VERSION_11, + timeout_millisec: 10_000, + local_address_is_ipv6: 0, + _padding: [0; 7], + access_point: EfiHttpConfigAccessPoint { + ipv4_node: &mut ipv4, + }, + }; + + unsafe { ((*http_protocol).configure)(http_protocol, &mut config) } +} + +fn destroy_http_child( + console: *mut EfiSimpleTextOutputProtocol, + service_binding: *mut EfiServiceBindingProtocol, + child_handle: EfiHandle, +) { + let destroy_status = + unsafe { ((*service_binding).destroy_child)(service_binding, child_handle) }; + write_console(console, "http_destroy_child_status: "); + write_status(console, destroy_status); + write_console(console, "\r\n"); +} diff --git a/httpboot-loader/src/uefi/loaded_image.rs b/httpboot-loader/src/uefi/loaded_image.rs new file mode 100644 index 00000000..07d76154 --- /dev/null +++ b/httpboot-loader/src/uefi/loaded_image.rs @@ -0,0 +1,73 @@ +use httpboot_loader::uri_from_device_path; + +use crate::uefi::abi::{ + EFI_LOADED_IMAGE_PROTOCOL_GUID, EfiDevicePathProtocol, EfiHandle, EfiLoadedImageProtocol, + EfiSystemTable, boot_services_from_system_table, +}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum LoaderError { + ProtocolUnavailable, + MissingFilePath, + DevicePathTooLarge, + InvalidDevicePath, +} + +pub fn loader_url_from_loaded_image<'a>( + image: EfiHandle, + system_table: *mut EfiSystemTable, + buffer: &'a mut [u8], +) -> Result<&'a str, LoaderError> { + let boot_services = + boot_services_from_system_table(system_table).ok_or(LoaderError::ProtocolUnavailable)?; + + let mut interface = core::ptr::null_mut(); + let status = + (boot_services.handle_protocol)(image, &EFI_LOADED_IMAGE_PROTOCOL_GUID, &mut interface); + if status.is_error() || interface.is_null() { + return Err(LoaderError::ProtocolUnavailable); + } + + let loaded_image = unsafe { (interface as *mut EfiLoadedImageProtocol).as_ref() } + .ok_or(LoaderError::ProtocolUnavailable)?; + if loaded_image.file_path.is_null() { + return Err(LoaderError::MissingFilePath); + } + + let size = copy_device_path_to_buffer(loaded_image.file_path, buffer)?; + uri_from_device_path(&buffer[..size]).map_err(|_| LoaderError::InvalidDevicePath) +} + +fn copy_device_path_to_buffer( + device_path: *const EfiDevicePathProtocol, + buffer: &mut [u8], +) -> Result { + let mut offset = 0; + let mut current = device_path; + + loop { + let node = unsafe { current.as_ref() }.ok_or(LoaderError::MissingFilePath)?; + let node_len = u16::from_le_bytes(node.length) as usize; + if node_len < 4 { + return Err(LoaderError::InvalidDevicePath); + } + if offset + node_len > buffer.len() { + return Err(LoaderError::DevicePathTooLarge); + } + + unsafe { + core::ptr::copy_nonoverlapping( + current as *const u8, + buffer.as_mut_ptr().add(offset), + node_len, + ); + } + offset += node_len; + + if node.node_type == 0x7f && node.node_subtype == 0xff { + return Ok(offset); + } + + current = unsafe { (current as *const u8).add(node_len) as *const EfiDevicePathProtocol }; + } +} diff --git a/httpboot-loader/src/uefi/mod.rs b/httpboot-loader/src/uefi/mod.rs new file mode 100644 index 00000000..bd3e464e --- /dev/null +++ b/httpboot-loader/src/uefi/mod.rs @@ -0,0 +1,4 @@ +pub mod abi; +pub mod console; +pub mod http; +pub mod loaded_image; From b114ceb09d5220d259e7cf09944553390e8e76c6 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 11 May 2026 08:39:04 +0000 Subject: [PATCH 11/39] feat: implement HTTP response handling and manifest parsing for UEFI loader --- httpboot-loader/src/uefi/abi.rs | 19 +++- httpboot-loader/src/uefi/http.rs | 183 ++++++++++++++++++++++++++++++- 2 files changed, 197 insertions(+), 5 deletions(-) diff --git a/httpboot-loader/src/uefi/abi.rs b/httpboot-loader/src/uefi/abi.rs index 40dcc0a1..e4b8c3fc 100644 --- a/httpboot-loader/src/uefi/abi.rs +++ b/httpboot-loader/src/uefi/abi.rs @@ -41,6 +41,7 @@ pub const EVT_NOTIFY_SIGNAL: u32 = 0x0000_0200; pub const TPL_CALLBACK: usize = 8; pub const HTTP_VERSION_11: u32 = 1; pub const HTTP_METHOD_GET: u32 = 0; +pub const HTTP_STATUS_200_OK: u32 = 3; #[repr(C)] pub struct EfiGuid { @@ -162,7 +163,8 @@ pub struct EfiHttpProtocol { pub request: extern "efiapi" fn(this: *mut EfiHttpProtocol, token: *mut EfiHttpToken) -> EfiStatus, pub cancel: usize, - pub response: usize, + pub response: + extern "efiapi" fn(this: *mut EfiHttpProtocol, token: *mut EfiHttpToken) -> EfiStatus, pub poll: extern "efiapi" fn(this: *mut EfiHttpProtocol) -> EfiStatus, } @@ -192,7 +194,7 @@ pub struct EfiHttpv4AccessPoint { #[repr(C)] pub union EfiHttpMessageData { pub request: *mut EfiHttpRequestData, - pub response: *mut c_void, + pub response: *mut EfiHttpResponseData, } #[repr(C)] @@ -201,11 +203,22 @@ pub struct EfiHttpRequestData { pub url: *mut u16, } +#[repr(C)] +pub struct EfiHttpResponseData { + pub status_code: u32, +} + +#[repr(C)] +pub struct EfiHttpHeader { + pub field_name: *mut u8, + pub field_value: *mut u8, +} + #[repr(C)] pub struct EfiHttpMessage { pub data: EfiHttpMessageData, pub header_count: usize, - pub headers: *mut c_void, + pub headers: *mut EfiHttpHeader, pub body_length: usize, pub body: *mut c_void, } diff --git a/httpboot-loader/src/uefi/http.rs b/httpboot-loader/src/uefi/http.rs index 1ed067f6..1c072787 100644 --- a/httpboot-loader/src/uefi/http.rs +++ b/httpboot-loader/src/uefi/http.rs @@ -4,13 +4,16 @@ use crate::uefi::abi::{ EFI_HTTP_PROTOCOL_GUID, EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, EFI_LOCATE_BY_PROTOCOL, EFI_NOT_READY, EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, EfiBootServices, EfiEvent, EfiGuid, EfiHandle, EfiHttpConfigAccessPoint, EfiHttpConfigData, EfiHttpMessage, EfiHttpMessageData, - EfiHttpProtocol, EfiHttpRequestData, EfiHttpToken, EfiHttpv4AccessPoint, + EfiHttpProtocol, EfiHttpRequestData, EfiHttpResponseData, EfiHttpToken, EfiHttpv4AccessPoint, EfiServiceBindingProtocol, EfiSimpleTextOutputProtocol, EfiStatus, EfiSystemTable, - HTTP_METHOD_GET, HTTP_VERSION_11, TPL_CALLBACK, boot_services_from_system_table, + HTTP_METHOD_GET, HTTP_STATUS_200_OK, HTTP_VERSION_11, TPL_CALLBACK, + boot_services_from_system_table, }; use crate::uefi::console::{write_console, write_status, write_usize, write_utf16_nul}; +use httpboot_loader::parse_downloaded_manifest; const UTF16_URL_BUFFER_SIZE: usize = 1024; +const MANIFEST_BODY_BUFFER_SIZE: usize = 4096; const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; pub fn print_http_protocol_probe( @@ -250,6 +253,9 @@ fn request_manifest( write_console(console, "http_request_completion: "); write_status(console, completion); write_console(console, "\r\n"); + if !completion.is_error() { + receive_manifest_response(console, boot_services, http_protocol); + } } let close_status = (boot_services.close_event)(event); @@ -271,6 +277,179 @@ fn poll_http_token(http_protocol: *mut EfiHttpProtocol, token: &EfiHttpToken) -> unsafe { core::ptr::read_volatile(&token.status) } } +fn receive_manifest_response( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + http_protocol: *mut EfiHttpProtocol, +) { + let mut event = core::ptr::null_mut(); + let event_status = (boot_services.create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event_notify), + core::ptr::null_mut(), + &mut event, + ); + write_console(console, "http_response_event_status: "); + write_status(console, event_status); + write_console(console, "\r\n"); + if event_status.is_error() || event.is_null() { + return; + } + + let mut response_data = EfiHttpResponseData { status_code: 0 }; + let mut body = [0u8; MANIFEST_BODY_BUFFER_SIZE]; + let mut message = EfiHttpMessage { + data: EfiHttpMessageData { + response: &mut response_data, + }, + header_count: 0, + headers: core::ptr::null_mut(), + body_length: body.len(), + body: body.as_mut_ptr() as *mut c_void, + }; + let mut token = EfiHttpToken { + event, + status: EFI_NOT_READY, + message: &mut message, + }; + + let response_status = unsafe { ((*http_protocol).response)(http_protocol, &mut token) }; + write_console(console, "http_response_status: "); + write_status(console, response_status); + write_console(console, "\r\n"); + + if !response_status.is_error() { + let completion = poll_http_token(http_protocol, &token); + write_console(console, "http_response_completion: "); + write_status(console, completion); + write_console(console, "\r\n"); + if !completion.is_error() { + print_manifest_response(console, boot_services, &response_data, &message, &body); + } + } + + let close_status = (boot_services.close_event)(event); + write_console(console, "http_response_close_event_status: "); + write_status(console, close_status); + write_console(console, "\r\n"); +} + +fn print_manifest_response( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + response_data: &EfiHttpResponseData, + message: &EfiHttpMessage, + body: &[u8], +) { + write_console(console, "http_response_status_enum: "); + write_usize(console, response_data.status_code as usize); + write_console(console, "\r\n"); + write_console(console, "http_response_status_code: "); + write_http_status_code(console, response_data.status_code); + write_console(console, "\r\n"); + + write_console(console, "http_response_header_count: "); + write_usize(console, message.header_count); + write_console(console, "\r\n"); + + write_console(console, "http_response_body_length: "); + write_usize(console, message.body_length); + write_console(console, "\r\n"); + + if response_data.status_code != HTTP_STATUS_200_OK { + write_console( + console, + "manifest_parse_skipped: HTTP status is not 200\r\n", + ); + free_response_headers(boot_services, message); + return; + } + + if message.body_length > body.len() { + write_console(console, "manifest_parse_skipped: body buffer too small\r\n"); + free_response_headers(boot_services, message); + return; + } + + match parse_downloaded_manifest(&body[..message.body_length], body.len()) { + Ok(manifest) => { + write_console(console, "manifest_arch: "); + write_console(console, manifest.arch); + write_console(console, "\r\n"); + write_console(console, "manifest_kernel_url: "); + write_console(console, manifest.kernel_url); + write_console(console, "\r\n"); + write_console(console, "manifest_kernel_size: "); + write_usize(console, manifest.kernel_size as usize); + write_console(console, "\r\n"); + } + Err(_) => write_console(console, "manifest_parse_failed\r\n"), + } + + free_response_headers(boot_services, message); +} + +fn free_response_headers(boot_services: &mut EfiBootServices, message: &EfiHttpMessage) { + if !message.headers.is_null() { + let _ = (boot_services.free_pool)(message.headers as *mut c_void); + } +} + +fn write_http_status_code(console: *mut EfiSimpleTextOutputProtocol, status_code: u32) { + let numeric = match status_code { + 1 => Some(100), + 2 => Some(101), + 3 => Some(200), + 4 => Some(201), + 5 => Some(202), + 6 => Some(203), + 7 => Some(204), + 8 => Some(205), + 9 => Some(206), + 10 => Some(300), + 11 => Some(301), + 12 => Some(302), + 13 => Some(303), + 14 => Some(304), + 15 => Some(305), + 16 => Some(307), + 17 => Some(400), + 18 => Some(401), + 19 => Some(402), + 20 => Some(403), + 21 => Some(404), + 22 => Some(405), + 23 => Some(406), + 24 => Some(407), + 25 => Some(408), + 26 => Some(409), + 27 => Some(410), + 28 => Some(411), + 29 => Some(412), + 30 => Some(413), + 31 => Some(414), + 32 => Some(415), + 33 => Some(416), + 34 => Some(417), + 35 => Some(500), + 36 => Some(501), + 37 => Some(502), + 38 => Some(503), + 39 => Some(504), + 40 => Some(505), + 41 => Some(308), + 42 => Some(429), + _ => None, + }; + + if let Some(numeric) = numeric { + write_usize(console, numeric); + } else { + write_console(console, "unknown"); + } +} + fn configure_http_ipv4_default(http_protocol: *mut EfiHttpProtocol) -> EfiStatus { let mut ipv4 = EfiHttpv4AccessPoint { use_default_address: 1, From 881e40f6aa9ae57320c9405ae3e4b36ba6251a76 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 11 May 2026 08:54:29 +0000 Subject: [PATCH 12/39] feat: implement kernel HTTP probe request and response handling for UEFI loader --- httpboot-loader/src/uefi/http.rs | 193 ++++++++++++++++++++++++++++++- 1 file changed, 192 insertions(+), 1 deletion(-) diff --git a/httpboot-loader/src/uefi/http.rs b/httpboot-loader/src/uefi/http.rs index 1c072787..0b567ea5 100644 --- a/httpboot-loader/src/uefi/http.rs +++ b/httpboot-loader/src/uefi/http.rs @@ -14,6 +14,7 @@ use httpboot_loader::parse_downloaded_manifest; const UTF16_URL_BUFFER_SIZE: usize = 1024; const MANIFEST_BODY_BUFFER_SIZE: usize = 4096; +const KERNEL_PROBE_BODY_BUFFER_SIZE: usize = 16 * 1024; const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; pub fn print_http_protocol_probe( @@ -325,7 +326,14 @@ fn receive_manifest_response( write_status(console, completion); write_console(console, "\r\n"); if !completion.is_error() { - print_manifest_response(console, boot_services, &response_data, &message, &body); + print_manifest_response( + console, + boot_services, + http_protocol, + &response_data, + &message, + &body, + ); } } @@ -338,6 +346,7 @@ fn receive_manifest_response( fn print_manifest_response( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, + http_protocol: *mut EfiHttpProtocol, response_data: &EfiHttpResponseData, message: &EfiHttpMessage, body: &[u8], @@ -383,6 +392,13 @@ fn print_manifest_response( write_console(console, "manifest_kernel_size: "); write_usize(console, manifest.kernel_size as usize); write_console(console, "\r\n"); + request_kernel_probe( + console, + boot_services, + http_protocol, + manifest.kernel_url, + manifest.kernel_size, + ); } Err(_) => write_console(console, "manifest_parse_failed\r\n"), } @@ -390,6 +406,181 @@ fn print_manifest_response( free_response_headers(boot_services, message); } +fn request_kernel_probe( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + http_protocol: *mut EfiHttpProtocol, + kernel_url: &str, + kernel_size: u64, +) { + let mut url_buffer = [0u16; UTF16_URL_BUFFER_SIZE]; + let url = match write_utf16_nul(kernel_url, &mut url_buffer) { + Ok(url) => url, + Err(_) => { + write_console(console, "kernel_request_skipped: URL too long\r\n"); + return; + } + }; + + let mut event = core::ptr::null_mut(); + let event_status = (boot_services.create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event_notify), + core::ptr::null_mut(), + &mut event, + ); + write_console(console, "kernel_request_event_status: "); + write_status(console, event_status); + write_console(console, "\r\n"); + if event_status.is_error() || event.is_null() { + return; + } + + let mut request_data = EfiHttpRequestData { + method: HTTP_METHOD_GET, + url, + }; + let mut message = EfiHttpMessage { + data: EfiHttpMessageData { + request: &mut request_data, + }, + header_count: 0, + headers: core::ptr::null_mut(), + body_length: 0, + body: core::ptr::null_mut(), + }; + let mut token = EfiHttpToken { + event, + status: EFI_NOT_READY, + message: &mut message, + }; + + let request_status = unsafe { ((*http_protocol).request)(http_protocol, &mut token) }; + write_console(console, "kernel_request_status: "); + write_status(console, request_status); + write_console(console, "\r\n"); + + if !request_status.is_error() { + let completion = poll_http_token(http_protocol, &token); + write_console(console, "kernel_request_completion: "); + write_status(console, completion); + write_console(console, "\r\n"); + if !completion.is_error() { + receive_kernel_probe_response(console, boot_services, http_protocol, kernel_size); + } + } + + let close_status = (boot_services.close_event)(event); + write_console(console, "kernel_request_close_event_status: "); + write_status(console, close_status); + write_console(console, "\r\n"); +} + +fn receive_kernel_probe_response( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + http_protocol: *mut EfiHttpProtocol, + expected_kernel_size: u64, +) { + let mut event = core::ptr::null_mut(); + let event_status = (boot_services.create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event_notify), + core::ptr::null_mut(), + &mut event, + ); + write_console(console, "kernel_response_event_status: "); + write_status(console, event_status); + write_console(console, "\r\n"); + if event_status.is_error() || event.is_null() { + return; + } + + let mut response_data = EfiHttpResponseData { status_code: 0 }; + let mut body = [0u8; KERNEL_PROBE_BODY_BUFFER_SIZE]; + let mut message = EfiHttpMessage { + data: EfiHttpMessageData { + response: &mut response_data, + }, + header_count: 0, + headers: core::ptr::null_mut(), + body_length: body.len(), + body: body.as_mut_ptr() as *mut c_void, + }; + let mut token = EfiHttpToken { + event, + status: EFI_NOT_READY, + message: &mut message, + }; + + let response_status = unsafe { ((*http_protocol).response)(http_protocol, &mut token) }; + write_console(console, "kernel_response_status: "); + write_status(console, response_status); + write_console(console, "\r\n"); + + if !response_status.is_error() { + let completion = poll_http_token(http_protocol, &token); + write_console(console, "kernel_response_completion: "); + write_status(console, completion); + write_console(console, "\r\n"); + if !completion.is_error() { + print_kernel_probe_response( + console, + boot_services, + &response_data, + &message, + &body, + expected_kernel_size, + ); + } + } + + let close_status = (boot_services.close_event)(event); + write_console(console, "kernel_response_close_event_status: "); + write_status(console, close_status); + write_console(console, "\r\n"); +} + +fn print_kernel_probe_response( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + response_data: &EfiHttpResponseData, + message: &EfiHttpMessage, + body: &[u8], + expected_kernel_size: u64, +) { + write_console(console, "kernel_response_status_enum: "); + write_usize(console, response_data.status_code as usize); + write_console(console, "\r\n"); + write_console(console, "kernel_response_status_code: "); + write_http_status_code(console, response_data.status_code); + write_console(console, "\r\n"); + write_console(console, "kernel_response_header_count: "); + write_usize(console, message.header_count); + write_console(console, "\r\n"); + write_console(console, "kernel_response_body_length: "); + write_usize(console, message.body_length); + write_console(console, "\r\n"); + write_console(console, "kernel_expected_size: "); + write_usize(console, expected_kernel_size as usize); + write_console(console, "\r\n"); + write_console(console, "kernel_probe_buffer_size: "); + write_usize(console, body.len()); + write_console(console, "\r\n"); + + if response_data.status_code != HTTP_STATUS_200_OK { + write_console(console, "kernel_probe_skipped: HTTP status is not 200\r\n"); + } else if message.body_length > body.len() { + write_console(console, "kernel_probe_skipped: body buffer too small\r\n"); + } else { + write_console(console, "kernel_probe_received_prefix\r\n"); + } + + free_response_headers(boot_services, message); +} + fn free_response_headers(boot_services: &mut EfiBootServices, message: &EfiHttpMessage) { if !message.headers.is_null() { let _ = (boot_services.free_pool)(message.headers as *mut c_void); From 822ab80aa883b7d4a72bc14f8eeac0a5ca3ba32a Mon Sep 17 00:00:00 2001 From: Josen-B Date: Tue, 12 May 2026 00:47:08 +0000 Subject: [PATCH 13/39] fix: rename httpboot-loader crate to httpboot --- Cargo.lock | 2 +- Cargo.toml | 2 +- {httpboot-loader => httpboot}/Cargo.toml | 4 ++-- {httpboot-loader => httpboot}/README.md | 8 ++++---- {httpboot-loader => httpboot}/src/lib.rs | 0 {httpboot-loader => httpboot}/src/main.rs | 4 ++-- {httpboot-loader => httpboot}/src/uefi/abi.rs | 0 {httpboot-loader => httpboot}/src/uefi/console.rs | 0 {httpboot-loader => httpboot}/src/uefi/http.rs | 2 +- {httpboot-loader => httpboot}/src/uefi/loaded_image.rs | 2 +- {httpboot-loader => httpboot}/src/uefi/mod.rs | 0 ostool/src/run/httpboot.rs | 8 ++++---- 12 files changed, 16 insertions(+), 16 deletions(-) rename {httpboot-loader => httpboot}/Cargo.toml (90%) rename {httpboot-loader => httpboot}/README.md (75%) rename {httpboot-loader => httpboot}/src/lib.rs (100%) rename {httpboot-loader => httpboot}/src/main.rs (96%) rename {httpboot-loader => httpboot}/src/uefi/abi.rs (100%) rename {httpboot-loader => httpboot}/src/uefi/console.rs (100%) rename {httpboot-loader => httpboot}/src/uefi/http.rs (99%) rename {httpboot-loader => httpboot}/src/uefi/loaded_image.rs (98%) rename {httpboot-loader => httpboot}/src/uefi/mod.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 26c94746..5f04c330 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1291,7 +1291,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] -name = "httpboot-loader" +name = "httpboot" version = "0.1.0" [[package]] diff --git a/Cargo.toml b/Cargo.toml index fb1056f7..027dbdd8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = [ "jkconfig", "fitimage", "ostool-server", - "httpboot-loader", + "httpboot", ] resolver = "3" diff --git a/httpboot-loader/Cargo.toml b/httpboot/Cargo.toml similarity index 90% rename from httpboot-loader/Cargo.toml rename to httpboot/Cargo.toml index 536ceb5a..6ceba72c 100644 --- a/httpboot-loader/Cargo.toml +++ b/httpboot/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "httpboot-loader" +name = "httpboot" authors = ["柏乔森 "] categories = ["command-line-interface", "config"] description = "UEFI HTTP Boot bare-bin loader for ostool" @@ -14,7 +14,7 @@ publish = false path = "src/lib.rs" [[bin]] -name = "httpboot-loader" +name = "httpboot" path = "src/main.rs" required-features = ["uefi-app"] diff --git a/httpboot-loader/README.md b/httpboot/README.md similarity index 75% rename from httpboot-loader/README.md rename to httpboot/README.md index bcd713d7..b711b1c6 100644 --- a/httpboot-loader/README.md +++ b/httpboot/README.md @@ -14,13 +14,13 @@ Build the x86_64 stub after installing the target: ```bash rustup target add x86_64-unknown-uefi -cargo build -p httpboot-loader --features uefi-app --target x86_64-unknown-uefi -mkdir -p target/httpboot-loader -cp target/x86_64-unknown-uefi/debug/httpboot-loader.efi target/httpboot-loader/BOOTX64.EFI +cargo build -p httpboot --features uefi-app --target x86_64-unknown-uefi +mkdir -p target/httpboot +cp target/x86_64-unknown-uefi/debug/httpboot.efi target/httpboot/BOOTX64.EFI ``` Then set: ```toml -efi_loader_path = "target/httpboot-loader/BOOTX64.EFI" +efi_loader_path = "target/httpboot/BOOTX64.EFI" ``` diff --git a/httpboot-loader/src/lib.rs b/httpboot/src/lib.rs similarity index 100% rename from httpboot-loader/src/lib.rs rename to httpboot/src/lib.rs diff --git a/httpboot-loader/src/main.rs b/httpboot/src/main.rs similarity index 96% rename from httpboot-loader/src/main.rs rename to httpboot/src/main.rs index cc0fe3a2..0513a456 100644 --- a/httpboot-loader/src/main.rs +++ b/httpboot/src/main.rs @@ -8,7 +8,7 @@ compile_error!("the uefi-app feature must be built with a *-unknown-uefi target" use core::panic::PanicInfo; #[cfg(target_os = "uefi")] -use httpboot_loader::write_sibling_manifest_url; +use httpboot::write_sibling_manifest_url; #[cfg(target_os = "uefi")] mod uefi; @@ -37,7 +37,7 @@ pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTa return EFI_UNSUPPORTED; }; - write_console(console, "ostool HTTP Boot loader\r\n"); + write_console(console, "ostool HTTP Boot\r\n"); write_console(console, "manifest parser core linked\r\n"); let mut device_path_buffer = [0u8; DEVICE_PATH_BUFFER_SIZE]; diff --git a/httpboot-loader/src/uefi/abi.rs b/httpboot/src/uefi/abi.rs similarity index 100% rename from httpboot-loader/src/uefi/abi.rs rename to httpboot/src/uefi/abi.rs diff --git a/httpboot-loader/src/uefi/console.rs b/httpboot/src/uefi/console.rs similarity index 100% rename from httpboot-loader/src/uefi/console.rs rename to httpboot/src/uefi/console.rs diff --git a/httpboot-loader/src/uefi/http.rs b/httpboot/src/uefi/http.rs similarity index 99% rename from httpboot-loader/src/uefi/http.rs rename to httpboot/src/uefi/http.rs index 0b567ea5..262cd577 100644 --- a/httpboot-loader/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -10,7 +10,7 @@ use crate::uefi::abi::{ boot_services_from_system_table, }; use crate::uefi::console::{write_console, write_status, write_usize, write_utf16_nul}; -use httpboot_loader::parse_downloaded_manifest; +use httpboot::parse_downloaded_manifest; const UTF16_URL_BUFFER_SIZE: usize = 1024; const MANIFEST_BODY_BUFFER_SIZE: usize = 4096; diff --git a/httpboot-loader/src/uefi/loaded_image.rs b/httpboot/src/uefi/loaded_image.rs similarity index 98% rename from httpboot-loader/src/uefi/loaded_image.rs rename to httpboot/src/uefi/loaded_image.rs index 07d76154..a1d3f2ed 100644 --- a/httpboot-loader/src/uefi/loaded_image.rs +++ b/httpboot/src/uefi/loaded_image.rs @@ -1,4 +1,4 @@ -use httpboot_loader::uri_from_device_path; +use httpboot::uri_from_device_path; use crate::uefi::abi::{ EFI_LOADED_IMAGE_PROTOCOL_GUID, EfiDevicePathProtocol, EfiHandle, EfiLoadedImageProtocol, diff --git a/httpboot-loader/src/uefi/mod.rs b/httpboot/src/uefi/mod.rs similarity index 100% rename from httpboot-loader/src/uefi/mod.rs rename to httpboot/src/uefi/mod.rs diff --git a/ostool/src/run/httpboot.rs b/ostool/src/run/httpboot.rs index f8165f28..a8197c75 100644 --- a/ostool/src/run/httpboot.rs +++ b/ostool/src/run/httpboot.rs @@ -360,12 +360,12 @@ async fn upload_configured_loader( }; let loader_bytes = std::fs::read(efi_loader_path) - .with_context(|| format!("failed to read HTTP Boot loader {}", efi_loader_path))?; + .with_context(|| format!("failed to read HTTP Boot {}", efi_loader_path))?; let uploaded = client .upload_http_boot_file(session_id, loader_file, loader_bytes) .await .with_context(|| { - format!("failed to upload HTTP Boot loader `{loader_file}` from `{efi_loader_path}`") + format!("failed to upload HTTP Boot `{loader_file}` from `{efi_loader_path}`") })?; Ok(Some(uploaded)) } @@ -373,11 +373,11 @@ async fn upload_configured_loader( async fn verify_existing_loader_url(loader_url: &str) -> anyhow::Result<()> { let response = reqwest::get(loader_url) .await - .with_context(|| format!("failed to verify HTTP Boot loader URL `{loader_url}`"))?; + .with_context(|| format!("failed to verify HTTP Boot URL `{loader_url}`"))?; let status = response.status(); if !status.is_success() { anyhow::bail!( - "HTTP Boot loader URL `{loader_url}` returned {status}; set `efi_loader_path` in .httpboot.toml or pre-publish the loader" + "HTTP Boot URL `{loader_url}` returned {status}; set `efi_loader_path` in .httpboot.toml or pre-publish the loader" ); } Ok(()) From 8a8d65c766892a3dcf53d83c1700af71f24daa09 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Tue, 12 May 2026 00:55:29 +0000 Subject: [PATCH 14/39] feat: implement chunked kernel download to UEFI pool memory with checksum --- httpboot/src/uefi/abi.rs | 8 +- httpboot/src/uefi/http.rs | 166 ++++++++++++++++++++++++++++++-------- 2 files changed, 139 insertions(+), 35 deletions(-) diff --git a/httpboot/src/uefi/abi.rs b/httpboot/src/uefi/abi.rs index e4b8c3fc..b123b38e 100644 --- a/httpboot/src/uefi/abi.rs +++ b/httpboot/src/uefi/abi.rs @@ -4,8 +4,10 @@ pub type EfiHandle = *mut c_void; pub type EfiEvent = *mut c_void; pub type EfiLocateSearchType = u32; pub type EfiEventNotify = Option; +pub type EfiMemoryType = u32; pub const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; +pub const EFI_LOADER_DATA: EfiMemoryType = 2; #[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq)] @@ -75,7 +77,11 @@ pub struct EfiBootServices { pub _allocate_pages: usize, pub _free_pages: usize, pub _get_memory_map: usize, - pub _allocate_pool: usize, + pub allocate_pool: extern "efiapi" fn( + pool_type: EfiMemoryType, + size: usize, + buffer: *mut *mut c_void, + ) -> EfiStatus, pub free_pool: extern "efiapi" fn(buffer: *mut c_void) -> EfiStatus, pub create_event: extern "efiapi" fn( event_type: u32, diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index 262cd577..3979443a 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -1,12 +1,12 @@ use core::ffi::c_void; use crate::uefi::abi::{ - EFI_HTTP_PROTOCOL_GUID, EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, EFI_LOCATE_BY_PROTOCOL, - EFI_NOT_READY, EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, EfiBootServices, EfiEvent, EfiGuid, - EfiHandle, EfiHttpConfigAccessPoint, EfiHttpConfigData, EfiHttpMessage, EfiHttpMessageData, - EfiHttpProtocol, EfiHttpRequestData, EfiHttpResponseData, EfiHttpToken, EfiHttpv4AccessPoint, - EfiServiceBindingProtocol, EfiSimpleTextOutputProtocol, EfiStatus, EfiSystemTable, - HTTP_METHOD_GET, HTTP_STATUS_200_OK, HTTP_VERSION_11, TPL_CALLBACK, + EFI_HTTP_PROTOCOL_GUID, EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, EFI_LOADER_DATA, + EFI_LOCATE_BY_PROTOCOL, EFI_NOT_READY, EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, EfiBootServices, + EfiEvent, EfiGuid, EfiHandle, EfiHttpConfigAccessPoint, EfiHttpConfigData, EfiHttpMessage, + EfiHttpMessageData, EfiHttpProtocol, EfiHttpRequestData, EfiHttpResponseData, EfiHttpToken, + EfiHttpv4AccessPoint, EfiServiceBindingProtocol, EfiSimpleTextOutputProtocol, EfiStatus, + EfiSystemTable, HTTP_METHOD_GET, HTTP_STATUS_200_OK, HTTP_VERSION_11, TPL_CALLBACK, boot_services_from_system_table, }; use crate::uefi::console::{write_console, write_status, write_usize, write_utf16_nul}; @@ -14,8 +14,9 @@ use httpboot::parse_downloaded_manifest; const UTF16_URL_BUFFER_SIZE: usize = 1024; const MANIFEST_BODY_BUFFER_SIZE: usize = 4096; -const KERNEL_PROBE_BODY_BUFFER_SIZE: usize = 16 * 1024; +const KERNEL_RESPONSE_CHUNK_SIZE: usize = 16 * 1024; const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; +const MAX_KERNEL_DOWNLOAD_SIZE: usize = 256 * 1024 * 1024; pub fn print_http_protocol_probe( console: *mut EfiSimpleTextOutputProtocol, @@ -467,7 +468,7 @@ fn request_kernel_probe( write_status(console, completion); write_console(console, "\r\n"); if !completion.is_error() { - receive_kernel_probe_response(console, boot_services, http_protocol, kernel_size); + download_kernel_to_pool(console, boot_services, http_protocol, kernel_size); } } @@ -477,12 +478,94 @@ fn request_kernel_probe( write_console(console, "\r\n"); } -fn receive_kernel_probe_response( +fn download_kernel_to_pool( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, http_protocol: *mut EfiHttpProtocol, expected_kernel_size: u64, ) { + let Some(expected_size) = checked_kernel_size(console, expected_kernel_size) else { + return; + }; + + let mut kernel_buffer = core::ptr::null_mut(); + let allocate_status = + (boot_services.allocate_pool)(EFI_LOADER_DATA, expected_size, &mut kernel_buffer); + write_console(console, "kernel_allocate_pool_status: "); + write_status(console, allocate_status); + write_console(console, "\r\n"); + if allocate_status.is_error() || kernel_buffer.is_null() { + return; + } + + let mut downloaded = 0usize; + let mut checksum = 0u32; + let mut complete = false; + + while downloaded < expected_size { + let remaining = expected_size - downloaded; + let chunk_len = remaining.min(KERNEL_RESPONSE_CHUNK_SIZE); + let chunk = unsafe { (kernel_buffer as *mut u8).add(downloaded) }; + let Some(received) = + receive_kernel_chunk(console, boot_services, http_protocol, chunk, chunk_len) + else { + break; + }; + + if received == 0 { + write_console(console, "kernel_download_stopped: zero length chunk\r\n"); + break; + } + + checksum = checksum_add(checksum, unsafe { + core::slice::from_raw_parts(chunk, received) + }); + downloaded += received; + if downloaded == expected_size { + complete = true; + } + } + + write_console(console, "kernel_downloaded_size: "); + write_usize(console, downloaded); + write_console(console, "\r\n"); + write_console(console, "kernel_expected_size: "); + write_usize(console, expected_size); + write_console(console, "\r\n"); + write_console(console, "kernel_download_complete: "); + write_console(console, if complete { "yes\r\n" } else { "no\r\n" }); + write_console(console, "kernel_checksum32: 0x"); + write_hex_u32(console, checksum); + write_console(console, "\r\n"); + + let free_status = (boot_services.free_pool)(kernel_buffer); + write_console(console, "kernel_free_pool_status: "); + write_status(console, free_status); + write_console(console, "\r\n"); +} + +fn checked_kernel_size( + console: *mut EfiSimpleTextOutputProtocol, + expected_kernel_size: u64, +) -> Option { + if expected_kernel_size == 0 { + write_console(console, "kernel_download_skipped: zero size\r\n"); + return None; + } + if expected_kernel_size > MAX_KERNEL_DOWNLOAD_SIZE as u64 { + write_console(console, "kernel_download_skipped: size too large\r\n"); + return None; + } + Some(expected_kernel_size as usize) +} + +fn receive_kernel_chunk( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + http_protocol: *mut EfiHttpProtocol, + chunk: *mut u8, + chunk_len: usize, +) -> Option { let mut event = core::ptr::null_mut(); let event_status = (boot_services.create_event)( EVT_NOTIFY_SIGNAL, @@ -495,19 +578,18 @@ fn receive_kernel_probe_response( write_status(console, event_status); write_console(console, "\r\n"); if event_status.is_error() || event.is_null() { - return; + return None; } let mut response_data = EfiHttpResponseData { status_code: 0 }; - let mut body = [0u8; KERNEL_PROBE_BODY_BUFFER_SIZE]; let mut message = EfiHttpMessage { data: EfiHttpMessageData { response: &mut response_data, }, header_count: 0, headers: core::ptr::null_mut(), - body_length: body.len(), - body: body.as_mut_ptr() as *mut c_void, + body_length: chunk_len, + body: chunk as *mut c_void, }; let mut token = EfiHttpToken { event, @@ -526,14 +608,7 @@ fn receive_kernel_probe_response( write_status(console, completion); write_console(console, "\r\n"); if !completion.is_error() { - print_kernel_probe_response( - console, - boot_services, - &response_data, - &message, - &body, - expected_kernel_size, - ); + print_kernel_chunk_response(console, boot_services, &response_data, &message); } } @@ -541,15 +616,21 @@ fn receive_kernel_probe_response( write_console(console, "kernel_response_close_event_status: "); write_status(console, close_status); write_console(console, "\r\n"); + + if response_status.is_error() || token.status.is_error() { + return None; + } + if response_data.status_code != HTTP_STATUS_200_OK { + return None; + } + Some(message.body_length) } -fn print_kernel_probe_response( +fn print_kernel_chunk_response( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, response_data: &EfiHttpResponseData, message: &EfiHttpMessage, - body: &[u8], - expected_kernel_size: u64, ) { write_console(console, "kernel_response_status_enum: "); write_usize(console, response_data.status_code as usize); @@ -563,19 +644,14 @@ fn print_kernel_probe_response( write_console(console, "kernel_response_body_length: "); write_usize(console, message.body_length); write_console(console, "\r\n"); - write_console(console, "kernel_expected_size: "); - write_usize(console, expected_kernel_size as usize); - write_console(console, "\r\n"); - write_console(console, "kernel_probe_buffer_size: "); - write_usize(console, body.len()); - write_console(console, "\r\n"); if response_data.status_code != HTTP_STATUS_200_OK { - write_console(console, "kernel_probe_skipped: HTTP status is not 200\r\n"); - } else if message.body_length > body.len() { - write_console(console, "kernel_probe_skipped: body buffer too small\r\n"); + write_console( + console, + "kernel_download_stopped: HTTP status is not 200\r\n", + ); } else { - write_console(console, "kernel_probe_received_prefix\r\n"); + write_console(console, "kernel_chunk_received\r\n"); } free_response_headers(boot_services, message); @@ -587,6 +663,28 @@ fn free_response_headers(boot_services: &mut EfiBootServices, message: &EfiHttpM } } +fn checksum_add(mut checksum: u32, bytes: &[u8]) -> u32 { + for byte in bytes { + checksum = checksum.wrapping_add(*byte as u32); + } + checksum +} + +fn write_hex_u32(console: *mut EfiSimpleTextOutputProtocol, value: u32) { + let mut output = [0u8; 8]; + let mut shift = 28u32; + for byte in &mut output { + let digit = ((value >> shift) & 0xf) as u8; + *byte = match digit { + 0..=9 => b'0' + digit, + _ => b'a' + (digit - 10), + }; + shift = shift.saturating_sub(4); + } + let text = core::str::from_utf8(&output).unwrap_or("????????"); + write_console(console, text); +} + fn write_http_status_code(console: *mut EfiSimpleTextOutputProtocol, status_code: u32) { let numeric = match status_code { 1 => Some(100), From 7a2e6e1b518bc8bd5c9690dabbdb0f20f9c39835 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Tue, 12 May 2026 01:00:21 +0000 Subject: [PATCH 15/39] feat: download kernel to fixed load address using UEFI allocate_pages --- httpboot/src/uefi/abi.rs | 12 ++++- httpboot/src/uefi/http.rs | 102 +++++++++++++++++++++++++++++++------- 2 files changed, 95 insertions(+), 19 deletions(-) diff --git a/httpboot/src/uefi/abi.rs b/httpboot/src/uefi/abi.rs index b123b38e..4377e9c5 100644 --- a/httpboot/src/uefi/abi.rs +++ b/httpboot/src/uefi/abi.rs @@ -5,8 +5,11 @@ pub type EfiEvent = *mut c_void; pub type EfiLocateSearchType = u32; pub type EfiEventNotify = Option; pub type EfiMemoryType = u32; +pub type EfiAllocateType = u32; +pub type EfiPhysicalAddress = u64; pub const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; +pub const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 0; pub const EFI_LOADER_DATA: EfiMemoryType = 2; #[repr(transparent)] @@ -74,8 +77,13 @@ pub struct EfiBootServices { pub hdr: EfiTableHeader, pub _raise_tpl: usize, pub _restore_tpl: usize, - pub _allocate_pages: usize, - pub _free_pages: usize, + pub allocate_pages: extern "efiapi" fn( + allocate_type: EfiAllocateType, + memory_type: EfiMemoryType, + pages: usize, + memory: *mut EfiPhysicalAddress, + ) -> EfiStatus, + pub free_pages: extern "efiapi" fn(memory: EfiPhysicalAddress, pages: usize) -> EfiStatus, pub _get_memory_map: usize, pub allocate_pool: extern "efiapi" fn( pool_type: EfiMemoryType, diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index 3979443a..50f1a31e 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -1,13 +1,13 @@ use core::ffi::c_void; use crate::uefi::abi::{ - EFI_HTTP_PROTOCOL_GUID, EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, EFI_LOADER_DATA, - EFI_LOCATE_BY_PROTOCOL, EFI_NOT_READY, EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, EfiBootServices, - EfiEvent, EfiGuid, EfiHandle, EfiHttpConfigAccessPoint, EfiHttpConfigData, EfiHttpMessage, - EfiHttpMessageData, EfiHttpProtocol, EfiHttpRequestData, EfiHttpResponseData, EfiHttpToken, - EfiHttpv4AccessPoint, EfiServiceBindingProtocol, EfiSimpleTextOutputProtocol, EfiStatus, - EfiSystemTable, HTTP_METHOD_GET, HTTP_STATUS_200_OK, HTTP_VERSION_11, TPL_CALLBACK, - boot_services_from_system_table, + EFI_ALLOCATE_ADDRESS, EFI_HTTP_PROTOCOL_GUID, EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, + EFI_LOADER_DATA, EFI_LOCATE_BY_PROTOCOL, EFI_NOT_READY, EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, + EfiBootServices, EfiEvent, EfiGuid, EfiHandle, EfiHttpConfigAccessPoint, EfiHttpConfigData, + EfiHttpMessage, EfiHttpMessageData, EfiHttpProtocol, EfiHttpRequestData, EfiHttpResponseData, + EfiHttpToken, EfiHttpv4AccessPoint, EfiPhysicalAddress, EfiServiceBindingProtocol, + EfiSimpleTextOutputProtocol, EfiStatus, EfiSystemTable, HTTP_METHOD_GET, HTTP_STATUS_200_OK, + HTTP_VERSION_11, TPL_CALLBACK, boot_services_from_system_table, }; use crate::uefi::console::{write_console, write_status, write_usize, write_utf16_nul}; use httpboot::parse_downloaded_manifest; @@ -17,6 +17,7 @@ const MANIFEST_BODY_BUFFER_SIZE: usize = 4096; const KERNEL_RESPONSE_CHUNK_SIZE: usize = 16 * 1024; const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; const MAX_KERNEL_DOWNLOAD_SIZE: usize = 256 * 1024 * 1024; +const EFI_PAGE_SIZE: usize = 4096; pub fn print_http_protocol_probe( console: *mut EfiSimpleTextOutputProtocol, @@ -399,6 +400,7 @@ fn print_manifest_response( http_protocol, manifest.kernel_url, manifest.kernel_size, + manifest.kernel_load_addr, ); } Err(_) => write_console(console, "manifest_parse_failed\r\n"), @@ -413,6 +415,7 @@ fn request_kernel_probe( http_protocol: *mut EfiHttpProtocol, kernel_url: &str, kernel_size: u64, + kernel_load_addr: u64, ) { let mut url_buffer = [0u16; UTF16_URL_BUFFER_SIZE]; let url = match write_utf16_nul(kernel_url, &mut url_buffer) { @@ -468,7 +471,13 @@ fn request_kernel_probe( write_status(console, completion); write_console(console, "\r\n"); if !completion.is_error() { - download_kernel_to_pool(console, boot_services, http_protocol, kernel_size); + download_kernel_to_load_addr( + console, + boot_services, + http_protocol, + kernel_size, + kernel_load_addr, + ); } } @@ -478,23 +487,38 @@ fn request_kernel_probe( write_console(console, "\r\n"); } -fn download_kernel_to_pool( +fn download_kernel_to_load_addr( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, http_protocol: *mut EfiHttpProtocol, expected_kernel_size: u64, + kernel_load_addr: u64, ) { let Some(expected_size) = checked_kernel_size(console, expected_kernel_size) else { return; }; - let mut kernel_buffer = core::ptr::null_mut(); - let allocate_status = - (boot_services.allocate_pool)(EFI_LOADER_DATA, expected_size, &mut kernel_buffer); - write_console(console, "kernel_allocate_pool_status: "); + let Some(page_count) = kernel_page_count(console, kernel_load_addr, expected_size) else { + return; + }; + + let mut target = kernel_load_addr as EfiPhysicalAddress; + let allocate_status = (boot_services.allocate_pages)( + EFI_ALLOCATE_ADDRESS, + EFI_LOADER_DATA, + page_count, + &mut target, + ); + write_console(console, "kernel_allocate_pages_status: "); write_status(console, allocate_status); write_console(console, "\r\n"); - if allocate_status.is_error() || kernel_buffer.is_null() { + write_console(console, "kernel_target_addr: 0x"); + write_hex_u64(console, target); + write_console(console, "\r\n"); + write_console(console, "kernel_target_pages: "); + write_usize(console, page_count); + write_console(console, "\r\n"); + if allocate_status.is_error() || target != kernel_load_addr { return; } @@ -505,7 +529,7 @@ fn download_kernel_to_pool( while downloaded < expected_size { let remaining = expected_size - downloaded; let chunk_len = remaining.min(KERNEL_RESPONSE_CHUNK_SIZE); - let chunk = unsafe { (kernel_buffer as *mut u8).add(downloaded) }; + let chunk = unsafe { (kernel_load_addr as *mut u8).add(downloaded) }; let Some(received) = receive_kernel_chunk(console, boot_services, http_protocol, chunk, chunk_len) else { @@ -538,8 +562,8 @@ fn download_kernel_to_pool( write_hex_u32(console, checksum); write_console(console, "\r\n"); - let free_status = (boot_services.free_pool)(kernel_buffer); - write_console(console, "kernel_free_pool_status: "); + let free_status = (boot_services.free_pages)(kernel_load_addr, page_count); + write_console(console, "kernel_free_pages_status: "); write_status(console, free_status); write_console(console, "\r\n"); } @@ -559,6 +583,35 @@ fn checked_kernel_size( Some(expected_kernel_size as usize) } +fn kernel_page_count( + console: *mut EfiSimpleTextOutputProtocol, + kernel_load_addr: u64, + expected_size: usize, +) -> Option { + if kernel_load_addr as usize as u64 != kernel_load_addr { + write_console( + console, + "kernel_download_skipped: load address too large\r\n", + ); + return None; + } + if kernel_load_addr as usize % EFI_PAGE_SIZE != 0 { + write_console( + console, + "kernel_download_skipped: load address is not page aligned\r\n", + ); + return None; + } + expected_size + .checked_add(EFI_PAGE_SIZE - 1) + .map(|size| size / EFI_PAGE_SIZE) + .filter(|pages| *pages > 0) + .or_else(|| { + write_console(console, "kernel_download_skipped: page count overflow\r\n"); + None + }) +} + fn receive_kernel_chunk( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, @@ -685,6 +738,21 @@ fn write_hex_u32(console: *mut EfiSimpleTextOutputProtocol, value: u32) { write_console(console, text); } +fn write_hex_u64(console: *mut EfiSimpleTextOutputProtocol, value: u64) { + let mut output = [0u8; 16]; + let mut shift = 60u32; + for byte in &mut output { + let digit = ((value >> shift) & 0xf) as u8; + *byte = match digit { + 0..=9 => b'0' + digit, + _ => b'a' + (digit - 10), + }; + shift = shift.saturating_sub(4); + } + let text = core::str::from_utf8(&output).unwrap_or("????????????????"); + write_console(console, text); +} + fn write_http_status_code(console: *mut EfiSimpleTextOutputProtocol, status_code: u32) { let numeric = match status_code { 1 => Some(100), From 471216c0cc663df32ec05c9328b918f95543bd74 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Tue, 12 May 2026 01:05:27 +0000 Subject: [PATCH 16/39] feat: probe memory map and prepare kernel jump readiness for UEFI loader --- httpboot/src/main.rs | 2 +- httpboot/src/uefi/abi.rs | 17 ++++- httpboot/src/uefi/http.rs | 143 +++++++++++++++++++++++++++++++++++--- 3 files changed, 150 insertions(+), 12 deletions(-) diff --git a/httpboot/src/main.rs b/httpboot/src/main.rs index 0513a456..8f1ea8c5 100644 --- a/httpboot/src/main.rs +++ b/httpboot/src/main.rs @@ -77,7 +77,7 @@ pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTa console, "HTTP download backend is pending; manifest bytes parser linked\r\n", ); - print_http_protocol_probe(console, system_table, manifest_url); + print_http_protocol_probe(console, image, system_table, manifest_url); EFI_SUCCESS } diff --git a/httpboot/src/uefi/abi.rs b/httpboot/src/uefi/abi.rs index 4377e9c5..f024dbf1 100644 --- a/httpboot/src/uefi/abi.rs +++ b/httpboot/src/uefi/abi.rs @@ -84,7 +84,13 @@ pub struct EfiBootServices { memory: *mut EfiPhysicalAddress, ) -> EfiStatus, pub free_pages: extern "efiapi" fn(memory: EfiPhysicalAddress, pages: usize) -> EfiStatus, - pub _get_memory_map: usize, + pub get_memory_map: extern "efiapi" fn( + memory_map_size: *mut usize, + memory_map: *mut EfiMemoryDescriptor, + map_key: *mut usize, + descriptor_size: *mut usize, + descriptor_version: *mut u32, + ) -> EfiStatus, pub allocate_pool: extern "efiapi" fn( pool_type: EfiMemoryType, size: usize, @@ -139,6 +145,15 @@ pub struct EfiBootServices { ) -> EfiStatus, } +#[repr(C)] +pub struct EfiMemoryDescriptor { + pub memory_type: u32, + pub physical_start: EfiPhysicalAddress, + pub virtual_start: u64, + pub number_of_pages: u64, + pub attribute: u64, +} + #[repr(C)] pub struct EfiDevicePathProtocol { pub node_type: u8, diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index 50f1a31e..8147bf9b 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -5,9 +5,10 @@ use crate::uefi::abi::{ EFI_LOADER_DATA, EFI_LOCATE_BY_PROTOCOL, EFI_NOT_READY, EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, EfiBootServices, EfiEvent, EfiGuid, EfiHandle, EfiHttpConfigAccessPoint, EfiHttpConfigData, EfiHttpMessage, EfiHttpMessageData, EfiHttpProtocol, EfiHttpRequestData, EfiHttpResponseData, - EfiHttpToken, EfiHttpv4AccessPoint, EfiPhysicalAddress, EfiServiceBindingProtocol, - EfiSimpleTextOutputProtocol, EfiStatus, EfiSystemTable, HTTP_METHOD_GET, HTTP_STATUS_200_OK, - HTTP_VERSION_11, TPL_CALLBACK, boot_services_from_system_table, + EfiHttpToken, EfiHttpv4AccessPoint, EfiMemoryDescriptor, EfiPhysicalAddress, + EfiServiceBindingProtocol, EfiSimpleTextOutputProtocol, EfiStatus, EfiSystemTable, + HTTP_METHOD_GET, HTTP_STATUS_200_OK, HTTP_VERSION_11, TPL_CALLBACK, + boot_services_from_system_table, }; use crate::uefi::console::{write_console, write_status, write_usize, write_utf16_nul}; use httpboot::parse_downloaded_manifest; @@ -18,9 +19,11 @@ const KERNEL_RESPONSE_CHUNK_SIZE: usize = 16 * 1024; const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; const MAX_KERNEL_DOWNLOAD_SIZE: usize = 256 * 1024 * 1024; const EFI_PAGE_SIZE: usize = 4096; +const MEMORY_MAP_BUFFER_SIZE: usize = 64 * 1024; pub fn print_http_protocol_probe( console: *mut EfiSimpleTextOutputProtocol, + image: EfiHandle, system_table: *mut EfiSystemTable, manifest_url: Option<&str>, ) { @@ -50,7 +53,7 @@ pub fn print_http_protocol_probe( Err(_) => write_console(console, "failed to locate HTTP Protocol\r\n"), } - probe_http_child(console, boot_services, manifest_url); + probe_http_child(console, boot_services, image, manifest_url); } fn count_protocol_handles( @@ -119,6 +122,7 @@ fn open_protocol_on_handle( fn probe_http_child( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, + image: EfiHandle, manifest_url: Option<&str>, ) { let service_handle = @@ -186,7 +190,7 @@ fn probe_http_child( if let Some(manifest_url) = manifest_url { let mut url_buffer = [0u16; UTF16_URL_BUFFER_SIZE]; match write_utf16_nul(manifest_url, &mut url_buffer) { - Ok(url) => request_manifest(console, boot_services, http_protocol, url), + Ok(url) => request_manifest(console, boot_services, image, http_protocol, url), Err(_) => write_console(console, "http_request_skipped: URL too long\r\n"), } } else { @@ -209,6 +213,7 @@ fn probe_http_child( fn request_manifest( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, + image: EfiHandle, http_protocol: *mut EfiHttpProtocol, url: *mut u16, ) { @@ -257,7 +262,7 @@ fn request_manifest( write_status(console, completion); write_console(console, "\r\n"); if !completion.is_error() { - receive_manifest_response(console, boot_services, http_protocol); + receive_manifest_response(console, boot_services, image, http_protocol); } } @@ -283,6 +288,7 @@ fn poll_http_token(http_protocol: *mut EfiHttpProtocol, token: &EfiHttpToken) -> fn receive_manifest_response( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, + image: EfiHandle, http_protocol: *mut EfiHttpProtocol, ) { let mut event = core::ptr::null_mut(); @@ -331,6 +337,7 @@ fn receive_manifest_response( print_manifest_response( console, boot_services, + image, http_protocol, &response_data, &message, @@ -348,6 +355,7 @@ fn receive_manifest_response( fn print_manifest_response( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, + image: EfiHandle, http_protocol: *mut EfiHttpProtocol, response_data: &EfiHttpResponseData, message: &EfiHttpMessage, @@ -394,13 +402,21 @@ fn print_manifest_response( write_console(console, "manifest_kernel_size: "); write_usize(console, manifest.kernel_size as usize); write_console(console, "\r\n"); + write_console(console, "manifest_kernel_load_addr: 0x"); + write_hex_u64(console, manifest.kernel_load_addr); + write_console(console, "\r\n"); + write_console(console, "manifest_entry_point: 0x"); + write_hex_u64(console, manifest.entry_point); + write_console(console, "\r\n"); request_kernel_probe( console, boot_services, + image, http_protocol, manifest.kernel_url, manifest.kernel_size, manifest.kernel_load_addr, + manifest.entry_point, ); } Err(_) => write_console(console, "manifest_parse_failed\r\n"), @@ -412,10 +428,12 @@ fn print_manifest_response( fn request_kernel_probe( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, + image: EfiHandle, http_protocol: *mut EfiHttpProtocol, kernel_url: &str, kernel_size: u64, kernel_load_addr: u64, + entry_point: u64, ) { let mut url_buffer = [0u16; UTF16_URL_BUFFER_SIZE]; let url = match write_utf16_nul(kernel_url, &mut url_buffer) { @@ -474,9 +492,11 @@ fn request_kernel_probe( download_kernel_to_load_addr( console, boot_services, + image, http_protocol, kernel_size, kernel_load_addr, + entry_point, ); } } @@ -490,9 +510,11 @@ fn request_kernel_probe( fn download_kernel_to_load_addr( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, + image: EfiHandle, http_protocol: *mut EfiHttpProtocol, expected_kernel_size: u64, kernel_load_addr: u64, + entry_point: u64, ) { let Some(expected_size) = checked_kernel_size(console, expected_kernel_size) else { return; @@ -562,10 +584,22 @@ fn download_kernel_to_load_addr( write_hex_u32(console, checksum); write_console(console, "\r\n"); - let free_status = (boot_services.free_pages)(kernel_load_addr, page_count); - write_console(console, "kernel_free_pages_status: "); - write_status(console, free_status); - write_console(console, "\r\n"); + if complete { + print_jump_readiness( + console, + boot_services, + image, + kernel_load_addr, + entry_point, + expected_size, + page_count, + ); + } else { + let free_status = (boot_services.free_pages)(kernel_load_addr, page_count); + write_console(console, "kernel_free_pages_status: "); + write_status(console, free_status); + write_console(console, "\r\n"); + } } fn checked_kernel_size( @@ -679,6 +713,87 @@ fn receive_kernel_chunk( Some(message.body_length) } +fn print_jump_readiness( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + image: EfiHandle, + kernel_load_addr: u64, + entry_point: u64, + kernel_size: usize, + page_count: usize, +) { + write_console(console, "jump_ready_load_addr: 0x"); + write_hex_u64(console, kernel_load_addr); + write_console(console, "\r\n"); + write_console(console, "jump_ready_entry_point: 0x"); + write_hex_u64(console, entry_point); + write_console(console, "\r\n"); + write_console(console, "jump_ready_kernel_size: "); + write_usize(console, kernel_size); + write_console(console, "\r\n"); + write_console(console, "jump_ready_pages_retained: "); + write_usize(console, page_count); + write_console(console, "\r\n"); + + probe_memory_map(console, boot_services, image); + write_console( + console, + "jump_skipped: ExitBootServices and entry call pending\r\n", + ); +} + +fn probe_memory_map( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + image: EfiHandle, +) { + let mut memory_map_size = 0usize; + let mut map_key = 0usize; + let mut descriptor_size = 0usize; + let mut descriptor_version = 0u32; + let size_status = (boot_services.get_memory_map)( + &mut memory_map_size, + core::ptr::null_mut(), + &mut map_key, + &mut descriptor_size, + &mut descriptor_version, + ); + write_console(console, "memory_map_size_status: "); + write_status(console, size_status); + write_console(console, "\r\n"); + write_console(console, "memory_map_required_size: "); + write_usize(console, memory_map_size); + write_console(console, "\r\n"); + + let mut memory_map = [0u8; MEMORY_MAP_BUFFER_SIZE]; + let mut buffer_size = memory_map.len(); + let map_status = (boot_services.get_memory_map)( + &mut buffer_size, + memory_map.as_mut_ptr() as *mut EfiMemoryDescriptor, + &mut map_key, + &mut descriptor_size, + &mut descriptor_version, + ); + write_console(console, "memory_map_status: "); + write_status(console, map_status); + write_console(console, "\r\n"); + write_console(console, "memory_map_size: "); + write_usize(console, buffer_size); + write_console(console, "\r\n"); + write_console(console, "memory_map_key: "); + write_usize(console, map_key); + write_console(console, "\r\n"); + write_console(console, "memory_map_descriptor_size: "); + write_usize(console, descriptor_size); + write_console(console, "\r\n"); + write_console(console, "memory_map_descriptor_version: "); + write_usize(console, descriptor_version as usize); + write_console(console, "\r\n"); + write_console(console, "exit_boot_services_image: 0x"); + write_hex_usize(console, image as usize); + write_console(console, "\r\n"); +} + fn print_kernel_chunk_response( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, @@ -753,6 +868,14 @@ fn write_hex_u64(console: *mut EfiSimpleTextOutputProtocol, value: u64) { write_console(console, text); } +fn write_hex_usize(console: *mut EfiSimpleTextOutputProtocol, value: usize) { + if usize::BITS == 64 { + write_hex_u64(console, value as u64); + } else { + write_hex_u32(console, value as u32); + } +} + fn write_http_status_code(console: *mut EfiSimpleTextOutputProtocol, status_code: u32) { let numeric = match status_code { 1 => Some(100), From a53bda1e0a7aa0d71f381b47c2bab47a239e67ae Mon Sep 17 00:00:00 2001 From: Josen-B Date: Tue, 12 May 2026 01:21:49 +0000 Subject: [PATCH 17/39] feat: implement ExitBootServices call with retry and memory map abstraction for UEFI loader --- httpboot/src/uefi/abi.rs | 3 +- httpboot/src/uefi/http.rs | 137 ++++++++++++++++++++++++++++++++------ 2 files changed, 117 insertions(+), 23 deletions(-) diff --git a/httpboot/src/uefi/abi.rs b/httpboot/src/uefi/abi.rs index f024dbf1..0e7dab82 100644 --- a/httpboot/src/uefi/abi.rs +++ b/httpboot/src/uefi/abi.rs @@ -126,7 +126,8 @@ pub struct EfiBootServices { pub _start_image: usize, pub _exit: usize, pub _unload_image: usize, - pub _exit_boot_services: usize, + pub exit_boot_services: + extern "efiapi" fn(image_handle: EfiHandle, map_key: usize) -> EfiStatus, pub _get_next_monotonic_count: usize, pub _stall: usize, pub _set_watchdog_timer: usize, diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index 8147bf9b..e6d5716c 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -20,6 +20,7 @@ const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; const MAX_KERNEL_DOWNLOAD_SIZE: usize = 256 * 1024 * 1024; const EFI_PAGE_SIZE: usize = 4096; const MEMORY_MAP_BUFFER_SIZE: usize = 64 * 1024; +const ENABLE_EXIT_BOOT_SERVICES: bool = false; pub fn print_http_protocol_probe( console: *mut EfiSimpleTextOutputProtocol, @@ -736,6 +737,7 @@ fn print_jump_readiness( write_console(console, "\r\n"); probe_memory_map(console, boot_services, image); + maybe_exit_boot_services(console, boot_services, image); write_console( console, "jump_skipped: ExitBootServices and entry call pending\r\n", @@ -747,53 +749,144 @@ fn probe_memory_map( boot_services: &mut EfiBootServices, image: EfiHandle, ) { - let mut memory_map_size = 0usize; - let mut map_key = 0usize; - let mut descriptor_size = 0usize; - let mut descriptor_version = 0u32; - let size_status = (boot_services.get_memory_map)( - &mut memory_map_size, - core::ptr::null_mut(), - &mut map_key, - &mut descriptor_size, - &mut descriptor_version, - ); + let mut probe = MemoryMapProbe::new(); + let size_status = get_memory_map(boot_services, &mut probe, core::ptr::null_mut(), 0); write_console(console, "memory_map_size_status: "); write_status(console, size_status); write_console(console, "\r\n"); write_console(console, "memory_map_required_size: "); - write_usize(console, memory_map_size); + write_usize(console, probe.memory_map_size); write_console(console, "\r\n"); let mut memory_map = [0u8; MEMORY_MAP_BUFFER_SIZE]; - let mut buffer_size = memory_map.len(); - let map_status = (boot_services.get_memory_map)( - &mut buffer_size, + let map_status = get_memory_map( + boot_services, + &mut probe, memory_map.as_mut_ptr() as *mut EfiMemoryDescriptor, - &mut map_key, - &mut descriptor_size, - &mut descriptor_version, + memory_map.len(), ); write_console(console, "memory_map_status: "); write_status(console, map_status); write_console(console, "\r\n"); write_console(console, "memory_map_size: "); - write_usize(console, buffer_size); + write_usize(console, probe.memory_map_size); write_console(console, "\r\n"); write_console(console, "memory_map_key: "); - write_usize(console, map_key); + write_usize(console, probe.map_key); write_console(console, "\r\n"); write_console(console, "memory_map_descriptor_size: "); - write_usize(console, descriptor_size); + write_usize(console, probe.descriptor_size); write_console(console, "\r\n"); write_console(console, "memory_map_descriptor_version: "); - write_usize(console, descriptor_version as usize); + write_usize(console, probe.descriptor_version as usize); write_console(console, "\r\n"); write_console(console, "exit_boot_services_image: 0x"); write_hex_usize(console, image as usize); write_console(console, "\r\n"); } +struct MemoryMapProbe { + memory_map_size: usize, + map_key: usize, + descriptor_size: usize, + descriptor_version: u32, +} + +impl MemoryMapProbe { + fn new() -> Self { + Self { + memory_map_size: 0, + map_key: 0, + descriptor_size: 0, + descriptor_version: 0, + } + } +} + +fn get_memory_map( + boot_services: &mut EfiBootServices, + probe: &mut MemoryMapProbe, + memory_map: *mut EfiMemoryDescriptor, + memory_map_capacity: usize, +) -> EfiStatus { + probe.memory_map_size = memory_map_capacity; + (boot_services.get_memory_map)( + &mut probe.memory_map_size, + memory_map, + &mut probe.map_key, + &mut probe.descriptor_size, + &mut probe.descriptor_version, + ) +} + +fn maybe_exit_boot_services( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + image: EfiHandle, +) { + let mut memory_map = [0u8; MEMORY_MAP_BUFFER_SIZE]; + let mut probe = MemoryMapProbe::new(); + let map_status = get_memory_map( + boot_services, + &mut probe, + memory_map.as_mut_ptr() as *mut EfiMemoryDescriptor, + memory_map.len(), + ); + write_console(console, "exit_memory_map_status: "); + write_status(console, map_status); + write_console(console, "\r\n"); + write_console(console, "exit_memory_map_key: "); + write_usize(console, probe.map_key); + write_console(console, "\r\n"); + + if map_status.is_error() { + write_console( + console, + "exit_boot_services_skipped: memory map unavailable\r\n", + ); + return; + } + + if !ENABLE_EXIT_BOOT_SERVICES { + write_console(console, "exit_boot_services_skipped: disabled\r\n"); + return; + } + + let exit_status = (boot_services.exit_boot_services)(image, probe.map_key); + write_console(console, "exit_boot_services_status: "); + write_status(console, exit_status); + write_console(console, "\r\n"); + if exit_status.is_error() { + retry_exit_boot_services(console, boot_services, image); + } +} + +fn retry_exit_boot_services( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + image: EfiHandle, +) { + let mut memory_map = [0u8; MEMORY_MAP_BUFFER_SIZE]; + let mut probe = MemoryMapProbe::new(); + let map_status = get_memory_map( + boot_services, + &mut probe, + memory_map.as_mut_ptr() as *mut EfiMemoryDescriptor, + memory_map.len(), + ); + write_console(console, "exit_retry_memory_map_status: "); + write_status(console, map_status); + write_console(console, "\r\n"); + if map_status.is_error() { + return; + } + + let exit_status = (boot_services.exit_boot_services)(image, probe.map_key); + write_console(console, "exit_retry_boot_services_status: "); + write_status(console, exit_status); + write_console(console, "\r\n"); +} + fn print_kernel_chunk_response( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, From 73da97b78cb22dc53a8a2d2a65e824e2b094378f Mon Sep 17 00:00:00 2001 From: Josen-B Date: Tue, 12 May 2026 01:30:01 +0000 Subject: [PATCH 18/39] feat: add entry call module with arch-aware calling convention for UEFI loader --- httpboot/src/uefi/entry.rs | 133 +++++++++++++++++++++++++++++++++++++ httpboot/src/uefi/http.rs | 16 +++++ httpboot/src/uefi/mod.rs | 1 + 3 files changed, 150 insertions(+) create mode 100644 httpboot/src/uefi/entry.rs diff --git a/httpboot/src/uefi/entry.rs b/httpboot/src/uefi/entry.rs new file mode 100644 index 00000000..ba296eab --- /dev/null +++ b/httpboot/src/uefi/entry.rs @@ -0,0 +1,133 @@ +use crate::uefi::abi::EfiSimpleTextOutputProtocol; +use crate::uefi::console::{write_console, write_usize}; + +pub const ENABLE_ENTRY_CALL: bool = false; + +pub struct EntryPlan<'a> { + pub arch: &'a str, + pub load_addr: u64, + pub entry_point: u64, + pub kernel_size: usize, +} + +pub fn print_entry_plan(console: *mut EfiSimpleTextOutputProtocol, plan: &EntryPlan<'_>) { + write_console(console, "entry_call_arch: "); + write_console(console, plan.arch); + write_console(console, "\r\n"); + write_console(console, "entry_call_target_arch: "); + write_console(console, target_arch_name()); + write_console(console, "\r\n"); + write_console(console, "entry_call_convention: "); + write_console(console, calling_convention_note(plan.arch)); + write_console(console, "\r\n"); + write_console(console, "entry_call_load_addr: 0x"); + write_hex_u64(console, plan.load_addr); + write_console(console, "\r\n"); + write_console(console, "entry_call_entry_point: 0x"); + write_hex_u64(console, plan.entry_point); + write_console(console, "\r\n"); + write_console(console, "entry_call_kernel_size: "); + write_usize(console, plan.kernel_size); + write_console(console, "\r\n"); + write_console(console, "entry_call_enabled: "); + write_console( + console, + if ENABLE_ENTRY_CALL { + "yes\r\n" + } else { + "no\r\n" + }, + ); +} + +#[allow(dead_code)] +pub unsafe fn maybe_call_entry( + console: *mut EfiSimpleTextOutputProtocol, + plan: &EntryPlan<'_>, +) -> ! { + print_entry_plan(console, plan); + if ENABLE_ENTRY_CALL { + unsafe { call_entry(plan.entry_point) } + } else { + loop { + core::hint::spin_loop(); + } + } +} + +#[cfg(target_arch = "x86_64")] +#[allow(dead_code)] +unsafe fn call_entry(entry_point: u64) -> ! { + let entry: extern "sysv64" fn() -> ! = unsafe { core::mem::transmute(entry_point as usize) }; + entry() +} + +#[cfg(target_arch = "aarch64")] +unsafe fn call_entry(entry_point: u64) -> ! { + let entry: extern "C" fn() -> ! = unsafe { core::mem::transmute(entry_point as usize) }; + entry() +} + +#[cfg(target_arch = "riscv64")] +unsafe fn call_entry(entry_point: u64) -> ! { + let entry: extern "C" fn() -> ! = unsafe { core::mem::transmute(entry_point as usize) }; + entry() +} + +#[cfg(not(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "riscv64" +)))] +unsafe fn call_entry(_entry_point: u64) -> ! { + loop { + core::hint::spin_loop(); + } +} + +fn calling_convention_note(manifest_arch: &str) -> &'static str { + match (target_arch_name(), manifest_arch) { + ("x86_64", "x86_64") => "x86_64 extern sysv64 no-arg entry", + ("aarch64", "aarch64") => "aarch64 extern C no-arg entry", + ("riscv64", "riscv64") => "riscv64 extern C no-arg entry", + _ => "target/manifest arch mismatch or unvalidated entry ABI", + } +} + +fn target_arch_name() -> &'static str { + #[cfg(target_arch = "x86_64")] + { + "x86_64" + } + #[cfg(target_arch = "aarch64")] + { + "aarch64" + } + #[cfg(target_arch = "riscv64")] + { + "riscv64" + } + #[cfg(not(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "riscv64" + )))] + { + "unknown" + } +} + +fn write_hex_u64(console: *mut EfiSimpleTextOutputProtocol, value: u64) { + let mut output = [0u8; 16]; + let mut shift = 60u32; + for byte in &mut output { + let digit = ((value >> shift) & 0xf) as u8; + *byte = match digit { + 0..=9 => b'0' + digit, + _ => b'a' + (digit - 10), + }; + shift = shift.saturating_sub(4); + } + let text = core::str::from_utf8(&output).unwrap_or("????????????????"); + write_console(console, text); +} diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index e6d5716c..7e6f1789 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -11,6 +11,7 @@ use crate::uefi::abi::{ boot_services_from_system_table, }; use crate::uefi::console::{write_console, write_status, write_usize, write_utf16_nul}; +use crate::uefi::entry::{EntryPlan, print_entry_plan}; use httpboot::parse_downloaded_manifest; const UTF16_URL_BUFFER_SIZE: usize = 1024; @@ -418,6 +419,7 @@ fn print_manifest_response( manifest.kernel_size, manifest.kernel_load_addr, manifest.entry_point, + manifest.arch, ); } Err(_) => write_console(console, "manifest_parse_failed\r\n"), @@ -435,6 +437,7 @@ fn request_kernel_probe( kernel_size: u64, kernel_load_addr: u64, entry_point: u64, + arch: &str, ) { let mut url_buffer = [0u16; UTF16_URL_BUFFER_SIZE]; let url = match write_utf16_nul(kernel_url, &mut url_buffer) { @@ -498,6 +501,7 @@ fn request_kernel_probe( kernel_size, kernel_load_addr, entry_point, + arch, ); } } @@ -516,6 +520,7 @@ fn download_kernel_to_load_addr( expected_kernel_size: u64, kernel_load_addr: u64, entry_point: u64, + arch: &str, ) { let Some(expected_size) = checked_kernel_size(console, expected_kernel_size) else { return; @@ -592,6 +597,7 @@ fn download_kernel_to_load_addr( image, kernel_load_addr, entry_point, + arch, expected_size, page_count, ); @@ -720,6 +726,7 @@ fn print_jump_readiness( image: EfiHandle, kernel_load_addr: u64, entry_point: u64, + arch: &str, kernel_size: usize, page_count: usize, ) { @@ -735,6 +742,15 @@ fn print_jump_readiness( write_console(console, "jump_ready_pages_retained: "); write_usize(console, page_count); write_console(console, "\r\n"); + print_entry_plan( + console, + &EntryPlan { + arch, + load_addr: kernel_load_addr, + entry_point, + kernel_size, + }, + ); probe_memory_map(console, boot_services, image); maybe_exit_boot_services(console, boot_services, image); diff --git a/httpboot/src/uefi/mod.rs b/httpboot/src/uefi/mod.rs index bd3e464e..7ae70b19 100644 --- a/httpboot/src/uefi/mod.rs +++ b/httpboot/src/uefi/mod.rs @@ -1,4 +1,5 @@ pub mod abi; pub mod console; +pub mod entry; pub mod http; pub mod loaded_image; From d37193b8eed47ae9fc2bff5ac214bb66b90604c1 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Tue, 12 May 2026 01:42:42 +0000 Subject: [PATCH 19/39] feat: integrate entry point call into ExitBootServices flow for UEFI loader --- httpboot/src/uefi/entry.rs | 25 ++--------------------- httpboot/src/uefi/http.rs | 41 ++++++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/httpboot/src/uefi/entry.rs b/httpboot/src/uefi/entry.rs index ba296eab..90a2cd3e 100644 --- a/httpboot/src/uefi/entry.rs +++ b/httpboot/src/uefi/entry.rs @@ -1,8 +1,6 @@ use crate::uefi::abi::EfiSimpleTextOutputProtocol; use crate::uefi::console::{write_console, write_usize}; -pub const ENABLE_ENTRY_CALL: bool = false; - pub struct EntryPlan<'a> { pub arch: &'a str, pub load_addr: u64, @@ -29,30 +27,11 @@ pub fn print_entry_plan(console: *mut EfiSimpleTextOutputProtocol, plan: &EntryP write_console(console, "entry_call_kernel_size: "); write_usize(console, plan.kernel_size); write_console(console, "\r\n"); - write_console(console, "entry_call_enabled: "); - write_console( - console, - if ENABLE_ENTRY_CALL { - "yes\r\n" - } else { - "no\r\n" - }, - ); } #[allow(dead_code)] -pub unsafe fn maybe_call_entry( - console: *mut EfiSimpleTextOutputProtocol, - plan: &EntryPlan<'_>, -) -> ! { - print_entry_plan(console, plan); - if ENABLE_ENTRY_CALL { - unsafe { call_entry(plan.entry_point) } - } else { - loop { - core::hint::spin_loop(); - } - } +pub unsafe fn call_entry_point(plan: &EntryPlan<'_>) -> ! { + unsafe { call_entry(plan.entry_point) } } #[cfg(target_arch = "x86_64")] diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index 7e6f1789..99ed8742 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -11,7 +11,7 @@ use crate::uefi::abi::{ boot_services_from_system_table, }; use crate::uefi::console::{write_console, write_status, write_usize, write_utf16_nul}; -use crate::uefi::entry::{EntryPlan, print_entry_plan}; +use crate::uefi::entry::{EntryPlan, call_entry_point, print_entry_plan}; use httpboot::parse_downloaded_manifest; const UTF16_URL_BUFFER_SIZE: usize = 1024; @@ -21,7 +21,7 @@ const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; const MAX_KERNEL_DOWNLOAD_SIZE: usize = 256 * 1024 * 1024; const EFI_PAGE_SIZE: usize = 4096; const MEMORY_MAP_BUFFER_SIZE: usize = 64 * 1024; -const ENABLE_EXIT_BOOT_SERVICES: bool = false; +const ENABLE_BOOT_JUMP: bool = false; pub fn print_http_protocol_probe( console: *mut EfiSimpleTextOutputProtocol, @@ -751,9 +751,28 @@ fn print_jump_readiness( kernel_size, }, ); + write_console(console, "boot_jump_enabled: "); + write_console( + console, + if ENABLE_BOOT_JUMP { + "yes\r\n" + } else { + "no\r\n" + }, + ); probe_memory_map(console, boot_services, image); - maybe_exit_boot_services(console, boot_services, image); + maybe_exit_boot_services( + console, + boot_services, + image, + &EntryPlan { + arch, + load_addr: kernel_load_addr, + entry_point, + kernel_size, + }, + ); write_console( console, "jump_skipped: ExitBootServices and entry call pending\r\n", @@ -839,6 +858,7 @@ fn maybe_exit_boot_services( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, image: EfiHandle, + entry_plan: &EntryPlan<'_>, ) { let mut memory_map = [0u8; MEMORY_MAP_BUFFER_SIZE]; let mut probe = MemoryMapProbe::new(); @@ -863,8 +883,11 @@ fn maybe_exit_boot_services( return; } - if !ENABLE_EXIT_BOOT_SERVICES { - write_console(console, "exit_boot_services_skipped: disabled\r\n"); + if !ENABLE_BOOT_JUMP { + write_console( + console, + "exit_boot_services_skipped: boot jump disabled\r\n", + ); return; } @@ -873,7 +896,9 @@ fn maybe_exit_boot_services( write_status(console, exit_status); write_console(console, "\r\n"); if exit_status.is_error() { - retry_exit_boot_services(console, boot_services, image); + retry_exit_boot_services(console, boot_services, image, entry_plan); + } else { + unsafe { call_entry_point(entry_plan) }; } } @@ -881,6 +906,7 @@ fn retry_exit_boot_services( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, image: EfiHandle, + entry_plan: &EntryPlan<'_>, ) { let mut memory_map = [0u8; MEMORY_MAP_BUFFER_SIZE]; let mut probe = MemoryMapProbe::new(); @@ -901,6 +927,9 @@ fn retry_exit_boot_services( write_console(console, "exit_retry_boot_services_status: "); write_status(console, exit_status); write_console(console, "\r\n"); + if !exit_status.is_error() { + unsafe { call_entry_point(entry_plan) }; + } } fn print_kernel_chunk_response( From ea71760a9d830ef5bcf203d3e974b655b88593e8 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Tue, 12 May 2026 02:46:38 +0000 Subject: [PATCH 20/39] feat: add proxy DHCP service support for HTTP Boot --- httpboot/README.md | 13 +- ostool-server/src/config.rs | 20 ++ ostool-server/src/lib.rs | 8 +- ostool-server/src/main.rs | 3 +- ostool-server/src/proxy_dhcp.rs | 365 ++++++++++++++++++++++++++++++++ 5 files changed, 401 insertions(+), 8 deletions(-) create mode 100644 ostool-server/src/proxy_dhcp.rs diff --git a/httpboot/README.md b/httpboot/README.md index b711b1c6..2c12e5f9 100644 --- a/httpboot/README.md +++ b/httpboot/README.md @@ -1,4 +1,4 @@ -# ostool HTTP Boot Loader +# ostool HTTP Boot This crate contains the UEFI-side loader for `ostool run httpboot`. @@ -7,10 +7,12 @@ Current status: - The shared no-std core parses `manifest.json`. - The shared no-std core can extract a URI device path and derive the sibling `manifest.json` URL. - The `uefi-app` binary builds a minimal UEFI application stub for targets that Rust supports, such as `x86_64-unknown-uefi`. -- The stub opens Loaded Image Protocol, reads its file path URI, and prints the derived manifest URL. -- HTTP download, memory placement, UEFI Boot Services shutdown, cache handling, and the architecture-specific jump backend are intentionally kept as the next implementation boundary. +- The loader opens Loaded Image Protocol, reads its file path URI, and derives the sibling `manifest.json` URL. +- The loader uses UEFI HTTP Protocol to download `manifest.json` and the kernel `.bin`. +- The loader places the kernel at `kernel_load_addr`, prepares memory-map and `ExitBootServices` state, and prints the entry plan. +- The final boot jump is behind a default-off compile-time safety switch. -Build the x86_64 stub after installing the target: +Build the x86_64 loader after installing the target: ```bash rustup target add x86_64-unknown-uefi @@ -24,3 +26,6 @@ Then set: ```toml efi_loader_path = "target/httpboot/BOOTX64.EFI" ``` + +The LoongArch loader requires a LoongArch UEFI PE/COFF build path. Do not use +`BOOTX64.EFI` on a LoongArch board. diff --git a/ostool-server/src/config.rs b/ostool-server/src/config.rs index b0b3e24f..06f26d22 100644 --- a/ostool-server/src/config.rs +++ b/ostool-server/src/config.rs @@ -22,6 +22,8 @@ pub struct ServerConfig { pub tftp: TftpConfig, #[serde(default)] pub http_boot: HttpBootConfig, + #[serde(default)] + pub proxy_dhcp: ProxyDhcpConfig, pub network: TftpNetworkConfig, #[serde(default)] pub upload_limits: UploadLimitsConfig, @@ -61,6 +63,7 @@ impl ServerConfig { dtb_dir, tftp, http_boot, + proxy_dhcp: ProxyDhcpConfig::default(), network: TftpNetworkConfig::default(), upload_limits: UploadLimitsConfig::default(), } @@ -203,6 +206,23 @@ impl Default for HttpBootConfig { } } +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +pub struct ProxyDhcpConfig { + pub enabled: bool, + pub bind_addr: SocketAddr, + pub board_id: Option, +} + +impl Default for ProxyDhcpConfig { + fn default() -> Self { + Self { + enabled: false, + bind_addr: SocketAddr::from(([0, 0, 0, 0], 67)), + board_id: None, + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] pub struct UploadLimitsConfig { pub session_file_max_mib: u32, diff --git a/ostool-server/src/lib.rs b/ostool-server/src/lib.rs index a28cb540..c5eb7e61 100644 --- a/ostool-server/src/lib.rs +++ b/ostool-server/src/lib.rs @@ -8,6 +8,7 @@ pub mod dtb_store; pub mod http_boot; pub mod power; pub mod process; +pub mod proxy_dhcp; pub mod serial; pub mod session; pub mod state; @@ -17,9 +18,10 @@ pub mod web; pub use api::router::build_router; pub use config::{ BoardConfig, BootConfig, BuiltinTftpConfig, CustomPowerManagement, PowerManagementConfig, - PxeProfile, SerialConfig, SerialPortKey, SerialPortKeyKind, ServerConfig, SystemTftpdHpaConfig, - TftpConfig, TftpNetworkConfig, UbootProfile, UefiBootArch, UefiHttpProfile, UefiHttpStrategy, - UploadLimitsConfig, VirtualPowerManagement, ZhongshengRelayPowerManagement, + ProxyDhcpConfig, PxeProfile, SerialConfig, SerialPortKey, SerialPortKeyKind, ServerConfig, + SystemTftpdHpaConfig, TftpConfig, TftpNetworkConfig, UbootProfile, UefiBootArch, + UefiHttpProfile, UefiHttpStrategy, UploadLimitsConfig, VirtualPowerManagement, + ZhongshengRelayPowerManagement, }; pub use dtb_store::{DtbFile, DtbStore}; pub use state::{AppState, BoardLeaseState, build_app_state}; diff --git a/ostool-server/src/main.rs b/ostool-server/src/main.rs index 58e9360e..189ef0b3 100644 --- a/ostool-server/src/main.rs +++ b/ostool-server/src/main.rs @@ -4,7 +4,7 @@ use anyhow::Context; use clap::Parser; use log::info; use ostool_server::{ - ServerConfig, build_app_state, build_router, + ServerConfig, build_app_state, build_router, proxy_dhcp, tftp::service::{BuiltinTftpManager, SystemTftpdHpaManager, TftpManager}, }; @@ -43,6 +43,7 @@ async fn main() -> anyhow::Result<()> { { tftp_manager.reconcile().await?; } + let _proxy_dhcp_task = proxy_dhcp::spawn_proxy_dhcp(state.clone()).await?; let gc_state = state.clone(); tokio::spawn(async move { diff --git a/ostool-server/src/proxy_dhcp.rs b/ostool-server/src/proxy_dhcp.rs new file mode 100644 index 00000000..b5a4cad9 --- /dev/null +++ b/ostool-server/src/proxy_dhcp.rs @@ -0,0 +1,365 @@ +use std::{collections::BTreeMap, net::Ipv4Addr, sync::Arc}; + +use anyhow::{Context, bail}; +use tokio::net::UdpSocket; + +use crate::{ + config::{BoardConfig, BootConfig, ServerConfig, UefiBootArch}, + state::AppState, +}; + +const DHCP_CLIENT_PORT: u16 = 68; +const DHCP_MAGIC_COOKIE: [u8; 4] = [99, 130, 83, 99]; +const DHCP_DISCOVER: u8 = 1; +const DHCP_OFFER: u8 = 2; +const DHCP_OPTION_PAD: u8 = 0; +const DHCP_OPTION_SUBNET_MASK: u8 = 1; +const DHCP_OPTION_ROUTER: u8 = 3; +const DHCP_OPTION_DNS: u8 = 6; +const DHCP_OPTION_MESSAGE_TYPE: u8 = 53; +const DHCP_OPTION_SERVER_ID: u8 = 54; +const DHCP_OPTION_VENDOR_CLASS: u8 = 60; +const DHCP_OPTION_BOOTFILE_NAME: u8 = 67; +const DHCP_OPTION_ARCH: u8 = 93; +const DHCP_OPTION_END: u8 = 255; +const BOOTP_FIXED_HEADER_LEN: usize = 236; +const DHCP_OPTIONS_OFFSET: usize = BOOTP_FIXED_HEADER_LEN + DHCP_MAGIC_COOKIE.len(); +const BOOTFILE_OFFSET: usize = 108; +const BOOTFILE_LEN: usize = 128; +const CHADDR_OFFSET: usize = 28; +const CHADDR_LEN: usize = 16; + +#[derive(Debug)] +struct DhcpRequest<'a> { + xid: [u8; 4], + secs: [u8; 2], + flags: [u8; 2], + chaddr: [u8; CHADDR_LEN], + vendor_class: Option<&'a [u8]>, + arch: Option, + message_type: Option, +} + +pub async fn spawn_proxy_dhcp( + state: AppState, +) -> anyhow::Result>> { + let config = state.config.read().await.clone(); + if !config.proxy_dhcp.enabled { + return Ok(None); + } + + let plan = build_boot_plan(&config, &state).await?; + let socket = Arc::new( + UdpSocket::bind(config.proxy_dhcp.bind_addr) + .await + .with_context(|| { + format!( + "failed to bind ProxyDHCP on {}", + config.proxy_dhcp.bind_addr + ) + })?, + ); + socket + .set_broadcast(true) + .context("failed to enable ProxyDHCP broadcast replies")?; + + log::info!( + "ProxyDHCP listening on {}, board={}, bootfile={}", + config.proxy_dhcp.bind_addr, + plan.board_id, + plan.boot_url + ); + + Ok(Some(tokio::spawn(async move { + let mut buf = [0u8; 1500]; + loop { + match socket.recv_from(&mut buf).await { + Ok((len, _peer)) => { + if let Err(err) = handle_packet(&socket, &buf[..len], &plan).await { + log::debug!("ProxyDHCP ignored packet: {err:#}"); + } + } + Err(err) => log::warn!("ProxyDHCP receive failed: {err}"), + } + } + }))) +} + +async fn handle_packet(socket: &UdpSocket, packet: &[u8], plan: &BootPlan) -> anyhow::Result<()> { + let request = parse_dhcp_request(packet)?; + if request.message_type != Some(DHCP_DISCOVER) { + bail!("not a DHCP Discover"); + } + if !is_http_client(request.vendor_class) { + bail!("not a UEFI HTTP client"); + } + if !arch_matches(request.arch, plan.arch.as_ref()) { + bail!("UEFI HTTP client arch does not match board"); + } + + let response = build_proxy_offer(packet, &request, plan)?; + socket + .send_to(&response, (Ipv4Addr::BROADCAST, DHCP_CLIENT_PORT)) + .await + .context("failed to send ProxyDHCP offer")?; + + log::info!( + "ProxyDHCP offered {} to {}", + plan.boot_url, + format_mac(&request.chaddr[..6]) + ); + Ok(()) +} + +#[derive(Clone, Debug)] +struct BootPlan { + board_id: String, + arch: Option, + server_ip: Ipv4Addr, + boot_url: String, +} + +async fn build_boot_plan(config: &ServerConfig, state: &AppState) -> anyhow::Result { + if !config.http_boot.enabled { + bail!("ProxyDHCP requires http_boot.enabled = true"); + } + + let boards = state.boards.read().await; + let (board_id, board) = select_board(config, &boards)?; + let BootConfig::UefiHttp(profile) = &board.boot else { + bail!("ProxyDHCP board `{board_id}` is not a uefi_http board"); + }; + + let loader_file = profile + .loader_file + .clone() + .unwrap_or_else(|| default_loader_file(profile.boot_arch.as_ref())); + let boot_url = http_boot_url(config, board_id, &loader_file)?; + let server_ip = proxy_server_ip(config)?; + + Ok(BootPlan { + board_id: board_id.to_string(), + arch: profile.boot_arch.clone(), + server_ip, + boot_url, + }) +} + +fn select_board<'a>( + config: &ServerConfig, + boards: &'a BTreeMap, +) -> anyhow::Result<(&'a str, &'a BoardConfig)> { + if let Some(board_id) = config.proxy_dhcp.board_id.as_deref() { + let board = boards + .get(board_id) + .ok_or_else(|| anyhow::anyhow!("ProxyDHCP board `{board_id}` not found"))?; + return Ok((board.id.as_str(), board)); + } + + let mut matches = boards + .iter() + .filter(|(_, board)| !board.disabled && matches!(board.boot, BootConfig::UefiHttp(_))); + let Some((board_id, board)) = matches.next() else { + bail!("ProxyDHCP enabled but no enabled uefi_http board exists"); + }; + if matches.next().is_some() { + bail!("ProxyDHCP needs proxy_dhcp.board_id when multiple uefi_http boards exist"); + } + Ok((board_id, board)) +} + +fn proxy_server_ip(config: &ServerConfig) -> anyhow::Result { + if let Some(base) = config.http_boot.public_base_url.as_deref() + && let Some(rest) = base.strip_prefix("http://") + { + let host = rest.split([':', '/']).next().unwrap_or_default(); + if let Ok(ip) = host.parse() { + return Ok(ip); + } + } + match config.listen_addr.ip() { + std::net::IpAddr::V4(ip) if !ip.is_unspecified() => Ok(ip), + _ => bail!("ProxyDHCP requires http_boot.public_base_url with an IPv4 host"), + } +} + +fn http_boot_url( + config: &ServerConfig, + board_id: &str, + relative_path: &str, +) -> anyhow::Result { + let base_url = config + .http_boot + .public_base_url + .clone() + .unwrap_or_else(|| format!("http://{}", config.listen_addr)); + let base_url = base_url.trim_end_matches('/'); + Ok(format!( + "{base_url}/boot/boards/{board_id}/current/{}", + relative_path.trim_start_matches('/') + )) +} + +fn default_loader_file(arch: Option<&UefiBootArch>) -> String { + match arch { + Some(UefiBootArch::X86_64) => "BOOTX64.EFI", + Some(UefiBootArch::Aarch64) => "BOOTAA64.EFI", + Some(UefiBootArch::Loongarch64) => "BOOTLOONGARCH64.EFI", + Some(UefiBootArch::Riscv64) => "BOOTRISCV64.EFI", + Some(UefiBootArch::Other) | None => "BOOT.EFI", + } + .to_string() +} + +fn parse_dhcp_request(packet: &[u8]) -> anyhow::Result> { + if packet.len() < DHCP_OPTIONS_OFFSET { + bail!("packet too short"); + } + if packet[0] != 1 { + bail!("not a BOOTREQUEST"); + } + if packet[236..240] != DHCP_MAGIC_COOKIE { + bail!("missing DHCP magic cookie"); + } + + let mut request = DhcpRequest { + xid: packet[4..8].try_into().unwrap(), + secs: packet[8..10].try_into().unwrap(), + flags: packet[10..12].try_into().unwrap(), + chaddr: packet[CHADDR_OFFSET..CHADDR_OFFSET + CHADDR_LEN] + .try_into() + .unwrap(), + vendor_class: None, + arch: None, + message_type: None, + }; + + for option in DhcpOptions::new(&packet[DHCP_OPTIONS_OFFSET..]) { + let (code, value) = option?; + match code { + DHCP_OPTION_MESSAGE_TYPE if value.len() == 1 => request.message_type = Some(value[0]), + DHCP_OPTION_VENDOR_CLASS => request.vendor_class = Some(value), + DHCP_OPTION_ARCH if value.len() >= 2 => { + request.arch = Some(u16::from_be_bytes([value[0], value[1]])); + } + _ => {} + } + } + + Ok(request) +} + +struct DhcpOptions<'a> { + bytes: &'a [u8], + offset: usize, +} + +impl<'a> DhcpOptions<'a> { + fn new(bytes: &'a [u8]) -> Self { + Self { bytes, offset: 0 } + } +} + +impl<'a> Iterator for DhcpOptions<'a> { + type Item = anyhow::Result<(u8, &'a [u8])>; + + fn next(&mut self) -> Option { + while self.offset < self.bytes.len() { + let code = self.bytes[self.offset]; + self.offset += 1; + if code == DHCP_OPTION_PAD { + continue; + } + if code == DHCP_OPTION_END { + return None; + } + if self.offset >= self.bytes.len() { + return Some(Err(anyhow::anyhow!("truncated DHCP option length"))); + } + let len = self.bytes[self.offset] as usize; + self.offset += 1; + if self.offset + len > self.bytes.len() { + return Some(Err(anyhow::anyhow!("truncated DHCP option value"))); + } + let value = &self.bytes[self.offset..self.offset + len]; + self.offset += len; + return Some(Ok((code, value))); + } + None + } +} + +fn is_http_client(vendor_class: Option<&[u8]>) -> bool { + vendor_class + .and_then(|bytes| core::str::from_utf8(bytes).ok()) + .is_some_and(|value| value.starts_with("HTTPClient:")) +} + +fn arch_matches(request_arch: Option, board_arch: Option<&UefiBootArch>) -> bool { + match (request_arch, board_arch) { + (Some(40), Some(UefiBootArch::Loongarch64)) => true, + (Some(16), Some(UefiBootArch::X86_64)) => true, + (Some(11), Some(UefiBootArch::Aarch64)) => true, + (_, None | Some(UefiBootArch::Other)) => true, + _ => false, + } +} + +fn build_proxy_offer( + request_packet: &[u8], + request: &DhcpRequest<'_>, + plan: &BootPlan, +) -> anyhow::Result> { + if plan.boot_url.len() > BOOTFILE_LEN { + bail!("ProxyDHCP boot URL is too long for BOOTP file field"); + } + + let mut response = vec![0u8; DHCP_OPTIONS_OFFSET]; + response[0] = 2; + response[1] = request_packet[1]; + response[2] = request_packet[2]; + response[3] = request_packet[3]; + response[4..8].copy_from_slice(&request.xid); + response[8..10].copy_from_slice(&request.secs); + response[10..12].copy_from_slice(&request.flags); + response[20..24].copy_from_slice(&plan.server_ip.octets()); + response[CHADDR_OFFSET..CHADDR_OFFSET + CHADDR_LEN].copy_from_slice(&request.chaddr); + response[BOOTFILE_OFFSET..BOOTFILE_OFFSET + plan.boot_url.len()] + .copy_from_slice(plan.boot_url.as_bytes()); + response[236..240].copy_from_slice(&DHCP_MAGIC_COOKIE); + + push_option(&mut response, DHCP_OPTION_MESSAGE_TYPE, &[DHCP_OFFER])?; + push_option( + &mut response, + DHCP_OPTION_SERVER_ID, + &plan.server_ip.octets(), + )?; + push_option( + &mut response, + DHCP_OPTION_BOOTFILE_NAME, + plan.boot_url.as_bytes(), + )?; + push_option(&mut response, DHCP_OPTION_SUBNET_MASK, &[255, 255, 255, 0])?; + push_option(&mut response, DHCP_OPTION_ROUTER, &plan.server_ip.octets())?; + push_option(&mut response, DHCP_OPTION_DNS, &plan.server_ip.octets())?; + response.push(DHCP_OPTION_END); + Ok(response) +} + +fn push_option(response: &mut Vec, code: u8, value: &[u8]) -> anyhow::Result<()> { + if value.len() > u8::MAX as usize { + bail!("DHCP option {code} value too long"); + } + response.push(code); + response.push(value.len() as u8); + response.extend_from_slice(value); + Ok(()) +} + +fn format_mac(bytes: &[u8]) -> String { + bytes + .iter() + .map(|byte| format!("{byte:02x}")) + .collect::>() + .join(":") +} From 96050c60b685fe4598ed3dc1e3a73dad9f4bab97 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Tue, 12 May 2026 03:07:42 +0000 Subject: [PATCH 21/39] feat: extend proxy DHCP to handle DHCP Request/ACK with configurable network parameters --- ostool-server/src/config.rs | 8 ++++ ostool-server/src/proxy_dhcp.rs | 84 ++++++++++++++++++++++++++++----- 2 files changed, 81 insertions(+), 11 deletions(-) diff --git a/ostool-server/src/config.rs b/ostool-server/src/config.rs index 06f26d22..2361fcc9 100644 --- a/ostool-server/src/config.rs +++ b/ostool-server/src/config.rs @@ -211,6 +211,10 @@ pub struct ProxyDhcpConfig { pub enabled: bool, pub bind_addr: SocketAddr, pub board_id: Option, + pub subnet_mask: Ipv4Addr, + pub router: Option, + pub dns_server: Option, + pub lease_time_secs: u32, } impl Default for ProxyDhcpConfig { @@ -219,6 +223,10 @@ impl Default for ProxyDhcpConfig { enabled: false, bind_addr: SocketAddr::from(([0, 0, 0, 0], 67)), board_id: None, + subnet_mask: Ipv4Addr::new(255, 255, 255, 0), + router: None, + dns_server: None, + lease_time_secs: 3600, } } } diff --git a/ostool-server/src/proxy_dhcp.rs b/ostool-server/src/proxy_dhcp.rs index b5a4cad9..74f96a9d 100644 --- a/ostool-server/src/proxy_dhcp.rs +++ b/ostool-server/src/proxy_dhcp.rs @@ -12,10 +12,14 @@ const DHCP_CLIENT_PORT: u16 = 68; const DHCP_MAGIC_COOKIE: [u8; 4] = [99, 130, 83, 99]; const DHCP_DISCOVER: u8 = 1; const DHCP_OFFER: u8 = 2; +const DHCP_REQUEST: u8 = 3; +const DHCP_ACK: u8 = 5; const DHCP_OPTION_PAD: u8 = 0; const DHCP_OPTION_SUBNET_MASK: u8 = 1; const DHCP_OPTION_ROUTER: u8 = 3; const DHCP_OPTION_DNS: u8 = 6; +const DHCP_OPTION_REQUESTED_IP: u8 = 50; +const DHCP_OPTION_LEASE_TIME: u8 = 51; const DHCP_OPTION_MESSAGE_TYPE: u8 = 53; const DHCP_OPTION_SERVER_ID: u8 = 54; const DHCP_OPTION_VENDOR_CLASS: u8 = 60; @@ -38,6 +42,7 @@ struct DhcpRequest<'a> { vendor_class: Option<&'a [u8]>, arch: Option, message_type: Option, + requested_ip: Option, } pub async fn spawn_proxy_dhcp( @@ -87,24 +92,43 @@ pub async fn spawn_proxy_dhcp( async fn handle_packet(socket: &UdpSocket, packet: &[u8], plan: &BootPlan) -> anyhow::Result<()> { let request = parse_dhcp_request(packet)?; - if request.message_type != Some(DHCP_DISCOVER) { - bail!("not a DHCP Discover"); - } + let response_type = match request.message_type { + Some(DHCP_DISCOVER) => DHCP_OFFER, + Some(DHCP_REQUEST) => DHCP_ACK, + _ => bail!("not a DHCP Discover/Request"), + }; if !is_http_client(request.vendor_class) { bail!("not a UEFI HTTP client"); } if !arch_matches(request.arch, plan.arch.as_ref()) { bail!("UEFI HTTP client arch does not match board"); } + if let Some(mac) = plan.client_mac.as_deref() { + let request_mac = format_mac(&request.chaddr[..6]); + if !mac.eq_ignore_ascii_case(&request_mac) { + bail!("UEFI HTTP client MAC does not match board"); + } + } + if request.message_type == Some(DHCP_REQUEST) + && let Some(requested_ip) = request.requested_ip + && requested_ip != plan.client_ip + { + bail!("DHCP Request is for a different client IP"); + } - let response = build_proxy_offer(packet, &request, plan)?; + let response = build_dhcp_response(packet, &request, plan, response_type)?; socket .send_to(&response, (Ipv4Addr::BROADCAST, DHCP_CLIENT_PORT)) .await - .context("failed to send ProxyDHCP offer")?; + .context("failed to send HTTP Boot DHCP response")?; log::info!( - "ProxyDHCP offered {} to {}", + "HTTP Boot DHCP sent {} with {} to {}", + if response_type == DHCP_ACK { + "ACK" + } else { + "OFFER" + }, plan.boot_url, format_mac(&request.chaddr[..6]) ); @@ -116,6 +140,12 @@ struct BootPlan { board_id: String, arch: Option, server_ip: Ipv4Addr, + client_ip: Ipv4Addr, + client_mac: Option, + subnet_mask: Ipv4Addr, + router: Ipv4Addr, + dns_server: Ipv4Addr, + lease_time_secs: u32, boot_url: String, } @@ -136,11 +166,22 @@ async fn build_boot_plan(config: &ServerConfig, state: &AppState) -> anyhow::Res .unwrap_or_else(|| default_loader_file(profile.boot_arch.as_ref())); let boot_url = http_boot_url(config, board_id, &loader_file)?; let server_ip = proxy_server_ip(config)?; + let client_ip = profile.client_ip.ok_or_else(|| { + anyhow::anyhow!("ProxyDHCP requires boot.client_ip for board `{board_id}`") + })?; + let router = config.proxy_dhcp.router.unwrap_or(server_ip); + let dns_server = config.proxy_dhcp.dns_server.unwrap_or(router); Ok(BootPlan { board_id: board_id.to_string(), arch: profile.boot_arch.clone(), server_ip, + client_ip, + client_mac: profile.mac_address.clone(), + subnet_mask: config.proxy_dhcp.subnet_mask, + router, + dns_server, + lease_time_secs: config.proxy_dhcp.lease_time_secs, boot_url, }) } @@ -232,6 +273,7 @@ fn parse_dhcp_request(packet: &[u8]) -> anyhow::Result> { vendor_class: None, arch: None, message_type: None, + requested_ip: None, }; for option in DhcpOptions::new(&packet[DHCP_OPTIONS_OFFSET..]) { @@ -239,6 +281,9 @@ fn parse_dhcp_request(packet: &[u8]) -> anyhow::Result> { match code { DHCP_OPTION_MESSAGE_TYPE if value.len() == 1 => request.message_type = Some(value[0]), DHCP_OPTION_VENDOR_CLASS => request.vendor_class = Some(value), + DHCP_OPTION_REQUESTED_IP if value.len() == 4 => { + request.requested_ip = Some(Ipv4Addr::new(value[0], value[1], value[2], value[3])); + } DHCP_OPTION_ARCH if value.len() >= 2 => { request.arch = Some(u16::from_be_bytes([value[0], value[1]])); } @@ -305,10 +350,11 @@ fn arch_matches(request_arch: Option, board_arch: Option<&UefiBootArch>) -> } } -fn build_proxy_offer( +fn build_dhcp_response( request_packet: &[u8], request: &DhcpRequest<'_>, plan: &BootPlan, + response_type: u8, ) -> anyhow::Result> { if plan.boot_url.len() > BOOTFILE_LEN { bail!("ProxyDHCP boot URL is too long for BOOTP file field"); @@ -322,26 +368,42 @@ fn build_proxy_offer( response[4..8].copy_from_slice(&request.xid); response[8..10].copy_from_slice(&request.secs); response[10..12].copy_from_slice(&request.flags); + response[16..20].copy_from_slice(&plan.client_ip.octets()); response[20..24].copy_from_slice(&plan.server_ip.octets()); response[CHADDR_OFFSET..CHADDR_OFFSET + CHADDR_LEN].copy_from_slice(&request.chaddr); response[BOOTFILE_OFFSET..BOOTFILE_OFFSET + plan.boot_url.len()] .copy_from_slice(plan.boot_url.as_bytes()); response[236..240].copy_from_slice(&DHCP_MAGIC_COOKIE); - push_option(&mut response, DHCP_OPTION_MESSAGE_TYPE, &[DHCP_OFFER])?; + push_option(&mut response, DHCP_OPTION_MESSAGE_TYPE, &[response_type])?; + if let Some(vendor_class) = request.vendor_class { + push_option(&mut response, DHCP_OPTION_VENDOR_CLASS, vendor_class)?; + } + if let Some(arch) = request.arch { + push_option(&mut response, DHCP_OPTION_ARCH, &arch.to_be_bytes())?; + } push_option( &mut response, DHCP_OPTION_SERVER_ID, &plan.server_ip.octets(), )?; + push_option( + &mut response, + DHCP_OPTION_LEASE_TIME, + &plan.lease_time_secs.to_be_bytes(), + )?; push_option( &mut response, DHCP_OPTION_BOOTFILE_NAME, plan.boot_url.as_bytes(), )?; - push_option(&mut response, DHCP_OPTION_SUBNET_MASK, &[255, 255, 255, 0])?; - push_option(&mut response, DHCP_OPTION_ROUTER, &plan.server_ip.octets())?; - push_option(&mut response, DHCP_OPTION_DNS, &plan.server_ip.octets())?; + push_option( + &mut response, + DHCP_OPTION_SUBNET_MASK, + &plan.subnet_mask.octets(), + )?; + push_option(&mut response, DHCP_OPTION_ROUTER, &plan.router.octets())?; + push_option(&mut response, DHCP_OPTION_DNS, &plan.dns_server.octets())?; response.push(DHCP_OPTION_END); Ok(response) } From 55d6345837de42e5bf84997f181c23169daff9b8 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Thu, 14 May 2026 02:58:54 +0000 Subject: [PATCH 22/39] feat: add LoongArch64 native UEFI loader and embedded manifest URL fallback --- httpboot/README.md | 39 +- httpboot/src/main.rs | 24 + loongarch64-uefi-loader/Cargo.toml | 11 + loongarch64-uefi-loader/Makefile | 49 + loongarch64-uefi-loader/README.md | 49 + loongarch64-uefi-loader/loader.c | 1042 ++++++++++++++++ loongarch64-uefi-loader/loader.lds | 47 + loongarch64-uefi-loader/src/main.rs | 1742 +++++++++++++++++++++++++++ ostool-server/src/api/router.rs | 23 + scripts/https_static_server.py | 27 + 10 files changed, 3051 insertions(+), 2 deletions(-) create mode 100644 loongarch64-uefi-loader/Cargo.toml create mode 100644 loongarch64-uefi-loader/Makefile create mode 100644 loongarch64-uefi-loader/README.md create mode 100644 loongarch64-uefi-loader/loader.c create mode 100644 loongarch64-uefi-loader/loader.lds create mode 100644 loongarch64-uefi-loader/src/main.rs create mode 100644 scripts/https_static_server.py diff --git a/httpboot/README.md b/httpboot/README.md index 2c12e5f9..b3da4697 100644 --- a/httpboot/README.md +++ b/httpboot/README.md @@ -8,6 +8,7 @@ Current status: - The shared no-std core can extract a URI device path and derive the sibling `manifest.json` URL. - The `uefi-app` binary builds a minimal UEFI application stub for targets that Rust supports, such as `x86_64-unknown-uefi`. - The loader opens Loaded Image Protocol, reads its file path URI, and derives the sibling `manifest.json` URL. +- When the loader is started from a local EFI system partition instead of HTTP Boot, it can use the compile-time `OSTOOL_HTTPBOOT_MANIFEST_URL` fallback. - The loader uses UEFI HTTP Protocol to download `manifest.json` and the kernel `.bin`. - The loader places the kernel at `kernel_load_addr`, prepares memory-map and `ExitBootServices` state, and prints the entry plan. - The final boot jump is behind a default-off compile-time safety switch. @@ -27,5 +28,39 @@ Then set: efi_loader_path = "target/httpboot/BOOTX64.EFI" ``` -The LoongArch loader requires a LoongArch UEFI PE/COFF build path. Do not use -`BOOTX64.EFI` on a LoongArch board. +For local ESP or removable-media boot, build the loader with an embedded manifest URL: + +```bash +OSTOOL_HTTPBOOT_MANIFEST_URL=http://10.3.10.229:2999/boot/boards/loongchip-httpboot-smoke/current/manifest.json \ + cargo build -p httpboot --features uefi-app --target x86_64-unknown-uefi +``` + +In that mode the firmware only needs to start the EFI application from disk/USB/ESP. +The loader still uses UEFI HTTP Protocol to download `manifest.json` and `kernel.bin`. + +LoongArch64 boards use the native C loader in: + +```text +loongarch64-uefi-loader/ +``` + +Build it with: + +```bash +make -C loongarch64-uefi-loader +``` + +The output is: + +```text +target/loongarch64-uefi-loader/BOOTLOONGARCH64.EFI +``` + +If UEFI Shell returns `Command Error Status: Unsupported` before printing +`ostool LoongArch64 UEFI loader`, rebuild this loader and copy the fresh output +to `EFI/BOOT/BOOTLOONGARCH64.EFI`. The native loader keeps `.text` at PE RVA +`0x1000` and emits a valid no-op `.reloc` block because some firmware rejects +EFI images whose first section starts at RVA `0x0` or whose relocation directory +is malformed. + +Do not use `BOOTX64.EFI` on a LoongArch board. diff --git a/httpboot/src/main.rs b/httpboot/src/main.rs index 8f1ea8c5..d7b31969 100644 --- a/httpboot/src/main.rs +++ b/httpboot/src/main.rs @@ -26,6 +26,8 @@ use uefi::loaded_image::{LoaderError, loader_url_from_loaded_image}; const DEVICE_PATH_BUFFER_SIZE: usize = 1024; #[cfg(target_os = "uefi")] const URL_BUFFER_SIZE: usize = 1024; +#[cfg(target_os = "uefi")] +const EMBEDDED_MANIFEST_URL_ENV: &str = "OSTOOL_HTTPBOOT_MANIFEST_URL"; #[cfg(target_os = "uefi")] #[unsafe(no_mangle)] @@ -73,6 +75,22 @@ pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTa } } + if manifest_url.is_none() { + match embedded_manifest_url() { + Some(url) => { + write_console(console, "embedded_manifest_url: "); + write_console(console, url); + write_console(console, "\r\n"); + manifest_url = Some(url); + } + None => { + write_console(console, "embedded_manifest_url_unset: "); + write_console(console, EMBEDDED_MANIFEST_URL_ENV); + write_console(console, "\r\n"); + } + } + } + write_console( console, "HTTP download backend is pending; manifest bytes parser linked\r\n", @@ -82,6 +100,12 @@ pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTa EFI_SUCCESS } +#[cfg(target_os = "uefi")] +fn embedded_manifest_url() -> Option<&'static str> { + let url = option_env!("OSTOOL_HTTPBOOT_MANIFEST_URL")?.trim(); + if url.is_empty() { None } else { Some(url) } +} + #[cfg(target_os = "uefi")] #[panic_handler] fn panic(_info: &PanicInfo<'_>) -> ! { diff --git a/loongarch64-uefi-loader/Cargo.toml b/loongarch64-uefi-loader/Cargo.toml new file mode 100644 index 00000000..56c7ba27 --- /dev/null +++ b/loongarch64-uefi-loader/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "loongarch64-uefi-loader" +version = "0.1.0" +edition = "2024" +publish = false + +[profile.release] +panic = "abort" +lto = false +codegen-units = 1 +opt-level = "s" diff --git a/loongarch64-uefi-loader/Makefile b/loongarch64-uefi-loader/Makefile new file mode 100644 index 00000000..0a0ff118 --- /dev/null +++ b/loongarch64-uefi-loader/Makefile @@ -0,0 +1,49 @@ +CROSS_COMPILE ?= loongarch64-linux-gnu- +LD := $(CROSS_COMPILE)ld +OBJCOPY := $(CROSS_COMPILE)objcopy +RUSTC ?= rustc +RUST_BOOT_JUMP_CFG := +ifeq ($(ENABLE_BOOT_JUMP),1) +RUST_BOOT_JUMP_CFG := --cfg ostool_enable_boot_jump +endif + +OUT_DIR ?= ../target/loongarch64-uefi-loader +TARGET := $(OUT_DIR)/BOOTLOONGARCH64.EFI +ELF := $(OUT_DIR)/ostool-loongarch64-loader.elf + +MANIFEST_URL ?= http://10.3.10.229:2999/boot/boards/loongchip-httpboot-smoke/current/manifest.json +ENABLE_BOOT_JUMP ?= 0 + +LDFLAGS := -nostdlib -znocombreloc -T loader.lds + +.PHONY: all clean + +all: $(TARGET) + +$(OUT_DIR): + mkdir -p $@ + +$(ELF): src/main.rs loader.lds | $(OUT_DIR) + OSTOOL_MANIFEST_URL="$(MANIFEST_URL)" \ + OSTOOL_ENABLE_BOOT_JUMP="$(ENABLE_BOOT_JUMP)" \ + $(RUSTC) --edition=2024 \ + --target loongarch64-unknown-none-softfloat \ + -C panic=abort \ + -C opt-level=s \ + -C relocation-model=static \ + -C code-model=medium \ + -C linker=$(LD) \ + -C link-arg=-nostdlib \ + -C link-arg=-znocombreloc \ + -C link-arg=-Tloader.lds \ + $(RUST_BOOT_JUMP_CFG) \ + -o $@ src/main.rs + +$(TARGET): $(ELF) + $(OBJCOPY) -O pei-loongarch64 \ + --subsystem=10 \ + -j .text -j .rodata -j .data -j .bss -j .reloc \ + $< $@ + +clean: + rm -rf $(OUT_DIR) diff --git a/loongarch64-uefi-loader/README.md b/loongarch64-uefi-loader/README.md new file mode 100644 index 00000000..e3e796e3 --- /dev/null +++ b/loongarch64-uefi-loader/README.md @@ -0,0 +1,49 @@ +# ostool LoongArch64 UEFI Loader + +This is the native LoongArch64 UEFI loader path for boards where DHCP HTTP Boot +URL delivery is not controllable. + +It intentionally does not use iPXE. The firmware starts: + +```text +EFI/BOOT/BOOTLOONGARCH64.EFI +``` + +The loader is implemented in Rust (`src/main.rs`). The previous C version is +kept as `loader.c` for reference while the board bring-up is still moving. + +The Rust loader then uses UEFI HTTP Protocol to download `manifest.json`, +downloads `kernel.bin` to `kernel_load_addr`, prints the entry plan, and keeps +the final jump behind `ENABLE_BOOT_JUMP=0` until the board-side observations are +stable. It currently matches the C bring-up path, including the TLS +Configuration probe and embedded temporary CA certificate used during HTTPS +validation. + +Build: + +```bash +make -C loongarch64-uefi-loader +``` + +The build uses Rust target `loongarch64-unknown-none-softfloat`, links with the +same `loader.lds` layout that was validated by the firmware, then converts the +ELF to `pei-loongarch64` via `loongarch64-linux-gnu-objcopy`. + +Override the manifest URL: + +```bash +make -C loongarch64-uefi-loader \ + MANIFEST_URL=http://10.3.10.229:2999/boot/boards/loongchip-httpboot-smoke/current/manifest.json +``` + +Enable the final jump only after download and memory-map observations are stable: + +```bash +make -C loongarch64-uefi-loader ENABLE_BOOT_JUMP=1 +``` + +Output: + +```text +target/loongarch64-uefi-loader/BOOTLOONGARCH64.EFI +``` diff --git a/loongarch64-uefi-loader/loader.c b/loongarch64-uefi-loader/loader.c new file mode 100644 index 00000000..c463a51f --- /dev/null +++ b/loongarch64-uefi-loader/loader.c @@ -0,0 +1,1042 @@ +#include +#include + +#ifndef OSTOOL_MANIFEST_URL +#define OSTOOL_MANIFEST_URL "http://10.3.10.229:2999/boot/boards/loongchip-httpboot-smoke/current/manifest.json" +#endif + +#ifndef OSTOOL_ENABLE_BOOT_JUMP +#define OSTOOL_ENABLE_BOOT_JUMP 0 +#endif + +typedef uint64_t efi_physical_address_t; +typedef uint64_t efi_virtual_address_t; +typedef void *efi_handle_t; +typedef void *efi_event_t; +typedef uint64_t efi_status_t; +typedef uint64_t efi_tpl_t; +typedef uint64_t efi_uintn_t; +typedef uint32_t efi_memory_type_t; +typedef uint32_t efi_allocate_type_t; +typedef uint32_t efi_locate_search_type_t; +typedef uint16_t efi_char16_t; + +#define EFI_SUCCESS 0 +#define EFI_ERROR_BIT (1ULL << 63) +#define EFI_LOAD_ERROR (EFI_ERROR_BIT | 1) +#define EFI_UNSUPPORTED (EFI_ERROR_BIT | 3) +#define EFI_BUFFER_TOO_SMALL (EFI_ERROR_BIT | 5) +#define EFI_NOT_READY (EFI_ERROR_BIT | 6) +#define EFI_DEVICE_ERROR (EFI_ERROR_BIT | 7) +#define EFI_NOT_FOUND (EFI_ERROR_BIT | 14) +#define EFI_ACCESS_DENIED (EFI_ERROR_BIT | 15) + +#define EFI_ALLOCATE_ADDRESS 0 +#define EFI_LOADER_DATA 2 +#define EFI_LOCATE_BY_PROTOCOL 2 +#define EVT_NOTIFY_SIGNAL 0x00000200U +#define TPL_CALLBACK 8 +#define EFI_PAGE_SIZE 4096 + +#define HTTP_VERSION_11 1 +#define HTTP_METHOD_GET 0 +#define HTTP_STATUS_200_OK 3 + +#define MANIFEST_MAX 4096 +#define URL16_MAX 1024 +#define KERNEL_CHUNK 16384 +#define MAX_KERNEL_SIZE (256U * 1024U * 1024U) +#define MEMORY_MAP_MAX 65536 +#define HTTP_POLL_LIMIT 1000000U + +typedef struct { + uint32_t data1; + uint16_t data2; + uint16_t data3; + uint8_t data4[8]; +} efi_guid_t; + +typedef struct { + uint64_t signature; + uint32_t revision; + uint32_t header_size; + uint32_t crc32; + uint32_t reserved; +} efi_table_header_t; + +typedef struct efi_simple_text_output_protocol efi_simple_text_output_protocol_t; +struct efi_simple_text_output_protocol { + void *reset; + efi_status_t (*output_string)(efi_simple_text_output_protocol_t *this, + const efi_char16_t *string); +}; + +typedef struct { + uint32_t type; + efi_physical_address_t physical_start; + efi_virtual_address_t virtual_start; + uint64_t number_of_pages; + uint64_t attribute; +} efi_memory_descriptor_t; + +typedef struct efi_boot_services efi_boot_services_t; +struct efi_boot_services { + efi_table_header_t hdr; + void *raise_tpl; + void *restore_tpl; + efi_status_t (*allocate_pages)(efi_allocate_type_t type, + efi_memory_type_t memory_type, + efi_uintn_t pages, + efi_physical_address_t *memory); + efi_status_t (*free_pages)(efi_physical_address_t memory, efi_uintn_t pages); + efi_status_t (*get_memory_map)(efi_uintn_t *memory_map_size, + efi_memory_descriptor_t *memory_map, + efi_uintn_t *map_key, + efi_uintn_t *descriptor_size, + uint32_t *descriptor_version); + efi_status_t (*allocate_pool)(efi_memory_type_t pool_type, + efi_uintn_t size, + void **buffer); + efi_status_t (*free_pool)(void *buffer); + efi_status_t (*create_event)(uint32_t type, + efi_tpl_t notify_tpl, + void (*notify_function)(efi_event_t event, void *context), + void *notify_context, + efi_event_t *event); + void *set_timer; + void *wait_for_event; + void *signal_event; + efi_status_t (*close_event)(efi_event_t event); + void *check_event; + void *install_protocol_interface; + void *reinstall_protocol_interface; + void *uninstall_protocol_interface; + efi_status_t (*handle_protocol)(efi_handle_t handle, + const efi_guid_t *protocol, + void **interface); + void *reserved; + void *register_protocol_notify; + void *locate_handle; + void *locate_device_path; + void *install_configuration_table; + void *load_image; + void *start_image; + void *exit; + void *unload_image; + efi_status_t (*exit_boot_services)(efi_handle_t image_handle, + efi_uintn_t map_key); + void *get_next_monotonic_count; + efi_status_t (*stall)(efi_uintn_t microseconds); + void *set_watchdog_timer; + void *connect_controller; + void *disconnect_controller; + void *open_protocol; + void *close_protocol; + void *open_protocol_information; + void *protocols_per_handle; + efi_status_t (*locate_handle_buffer)(efi_locate_search_type_t search_type, + const efi_guid_t *protocol, + void *search_key, + efi_uintn_t *no_handles, + efi_handle_t **buffer); +}; + +typedef struct { + efi_table_header_t hdr; + efi_char16_t *firmware_vendor; + uint32_t firmware_revision; + efi_handle_t console_in_handle; + void *con_in; + efi_handle_t console_out_handle; + efi_simple_text_output_protocol_t *con_out; + efi_handle_t standard_error_handle; + efi_simple_text_output_protocol_t *std_err; + void *runtime_services; + efi_boot_services_t *boot_services; +} efi_system_table_t; + +typedef struct efi_service_binding_protocol efi_service_binding_protocol_t; +struct efi_service_binding_protocol { + efi_status_t (*create_child)(efi_service_binding_protocol_t *this, + efi_handle_t *child_handle); + efi_status_t (*destroy_child)(efi_service_binding_protocol_t *this, + efi_handle_t child_handle); +}; + +typedef struct efi_http_protocol efi_http_protocol_t; +typedef struct efi_tls_configuration_protocol efi_tls_configuration_protocol_t; +typedef union { + void *ipv4_node; + void *ipv6_node; +} efi_http_config_access_point_t; + +typedef struct { + uint8_t use_default_address; + uint8_t local_address[4]; + uint8_t local_subnet[4]; + uint16_t local_port; +} efi_httpv4_access_point_t; + +typedef struct { + uint32_t http_version; + uint32_t timeout_millisec; + uint8_t local_address_is_ipv6; + uint8_t padding[7]; + efi_http_config_access_point_t access_point; +} efi_http_config_data_t; + +typedef struct { + uint32_t method; + efi_char16_t *url; +} efi_http_request_data_t; + +typedef struct { + uint32_t status_code; +} efi_http_response_data_t; + +typedef union { + efi_http_request_data_t *request; + efi_http_response_data_t *response; +} efi_http_message_data_t; + +typedef struct { + char *field_name; + char *field_value; +} efi_http_header_t; + +typedef struct { + efi_http_message_data_t data; + efi_uintn_t header_count; + efi_http_header_t *headers; + efi_uintn_t body_length; + void *body; +} efi_http_message_t; + +typedef struct { + efi_event_t event; + efi_status_t status; + efi_http_message_t *message; +} efi_http_token_t; + +struct efi_http_protocol { + void *get_mode_data; + efi_status_t (*configure)(efi_http_protocol_t *this, + efi_http_config_data_t *http_config_data); + efi_status_t (*request)(efi_http_protocol_t *this, efi_http_token_t *token); + void *cancel; + efi_status_t (*response)(efi_http_protocol_t *this, efi_http_token_t *token); + efi_status_t (*poll)(efi_http_protocol_t *this); +}; + +enum { + EFI_TLS_CONFIG_DATA_TYPE_HOST_PUBLIC_CERT = 0, + EFI_TLS_CONFIG_DATA_TYPE_HOST_PRIVATE_KEY = 1, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE = 2, + EFI_TLS_CONFIG_DATA_TYPE_CERT_REVOCATION_LIST = 3, +}; + +struct efi_tls_configuration_protocol { + efi_status_t (*set_data)(efi_tls_configuration_protocol_t *this, + uint32_t data_type, + void *data, + efi_uintn_t data_size); + efi_status_t (*get_data)(efi_tls_configuration_protocol_t *this, + uint32_t data_type, + void *data, + efi_uintn_t *data_size); +}; + +typedef struct { + char kernel_url[1024]; + uint64_t kernel_size; + uint64_t kernel_load_addr; + uint64_t entry_point; + char arch[32]; +} manifest_t; + +static const efi_guid_t efi_http_service_binding_protocol_guid = { + 0xbdc8e6af, 0xd9bc, 0x4379, {0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c} +}; + +static const efi_guid_t efi_http_protocol_guid = { + 0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b} +}; + +static const efi_guid_t efi_tls_service_binding_protocol_guid = { + 0x952cb795, 0xff36, 0x48cf, {0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d} +}; + +static const efi_guid_t efi_tls_configuration_protocol_guid = { + 0x1682fe44, 0xbd7a, 0x4407, {0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d} +}; + +static const efi_guid_t efi_tcp4_service_binding_protocol_guid = { + 0x00720665, 0x67eb, 0x4a99, {0xba, 0xf7, 0xd3, 0xc3, 0x3a, 0x1c, 0x7c, 0xc9} +}; + +static efi_simple_text_output_protocol_t *g_console; + +static char g_https_ca_pem[] = + "-----BEGIN CERTIFICATE-----\n" + "MIIDHjCCAgagAwIBAgIUBJubHQIousJm3ZT9sNPYq0u1AhwwDQYJKoZIhvcNAQEL\n" + "BQAwFjEUMBIGA1UEAwwLMTAuMy4xMC4yMjkwHhcNMjYwNTEzMDkxMTIwWhcNMjYw\n" + "NTIwMDkxMTIwWjAWMRQwEgYDVQQDDAsxMC4zLjEwLjIyOTCCASIwDQYJKoZIhvcN\n" + "AQEBBQADggEPADCCAQoCggEBALb3klUcff8fXYIcsgeQr1gs2rnwbOl/4Unwtulx\n" + "wG1K8joXYwWT4NP4XSOJy8aVuLk0FSd8VB29l6gjduSYzdC1CE9i3bzJnu4E96X/\n" + "EqRWP6QPkQJUizpH3qwxK1sDNJTmoAdq48v3cLgyyDdxzU/iVlWM51izk4njFMzZ\n" + "4PCLFfznANnj8o5diDCQ96uyKxmaXArIeDAAwcTSlJYc7QHWg6WEg+FQcn3TaMKJ\n" + "8rNELrKMrygc71ZdF9r6anud4YMouse6wJmEzGEVSCQ/y3dxd8gr1Ixq3DV9Yj9J\n" + "fZ57GWjWLTi1CWyMAAod8b6xr+o2yHRS2mGIfTEskTHTc+8CAwEAAaNkMGIwHQYD\n" + "VR0OBBYEFIimL7eY9PEocEUee1gz/YxTalmbMB8GA1UdIwQYMBaAFIimL7eY9PEo\n" + "cEUee1gz/YxTalmbMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0RBAgwBocECgMK5TAN\n" + "BgkqhkiG9w0BAQsFAAOCAQEAf1TkdDogQAYDgSUdraZ6WtOrD7MrLH69DZIcMrVf\n" + "GymOgar70uD9s1MEAwAsCgfqN8+kRcR/viWY8e86AzYVralqiLVs9tpR+vrnFejd\n" + "f9KLftc3owFwmiMLR5szwZMENOz2F+TJ8fNZBTXaJuITxrcIwuBym0FqL1pkN4hL\n" + "ikfU5paqfDst5LA/Wu/56XPtP8tFGh498jNsKlAumlQgaX0w+xxGiaGf1WkvTOP8\n" + "bVwyUYVeTIG2utpOKra0gkg42qcPdvRzZsT9REzlp2cxyBx5fkSmS0kXtqg4fT69\n" + "9/dZPxTWismXdZ4HN74kKak5tAB9CwKXvwaLRqOmXEg4hw==\n" + "-----END CERTIFICATE-----\n"; + +static size_t strlen8(const char *s) { + size_t len = 0; + while (s[len] != '\0') { + len++; + } + return len; +} + +static void memset8(void *dst, uint8_t value, size_t len) { + uint8_t *d = (uint8_t *)dst; + for (size_t i = 0; i < len; i++) { + d[i] = value; + } +} + +static int is_error(efi_status_t status) { + return (status & EFI_ERROR_BIT) != 0; +} + +static void write_ascii(const char *s) { + static efi_char16_t buf[256]; + if (!g_console) { + return; + } + while (*s) { + size_t n = 0; + while (s[n] && n + 1 < (sizeof(buf) / sizeof(buf[0]))) { + buf[n] = (uint8_t)s[n]; + n++; + } + buf[n] = 0; + g_console->output_string(g_console, buf); + s += n; + } +} + +static void write_hex64(uint64_t value) { + char out[17]; + for (int i = 0; i < 16; i++) { + uint8_t digit = (value >> ((15 - i) * 4)) & 0xf; + out[i] = (digit < 10) ? ('0' + digit) : ('a' + digit - 10); + } + out[16] = '\0'; + write_ascii(out); +} + +static void write_dec(uint64_t value) { + char out[32]; + size_t pos = sizeof(out); + out[--pos] = '\0'; + if (value == 0) { + out[--pos] = '0'; + } else { + while (value > 0 && pos > 0) { + out[--pos] = (char)('0' + (value % 10)); + value /= 10; + } + } + write_ascii(&out[pos]); +} + +static void write_status(const char *label, efi_status_t status) { + write_ascii(label); + write_ascii("0x"); + write_hex64(status); + write_ascii("\r\n"); +} + +static int write_utf16_url(const char *url, efi_char16_t *out, size_t cap) { + size_t len = strlen8(url); + if (len + 1 > cap) { + return -1; + } + for (size_t i = 0; i < len; i++) { + out[i] = (uint8_t)url[i]; + } + out[len] = 0; + return 0; +} + +static int write_https_probe_url(const char *url, efi_char16_t *out, size_t cap) { + const char http_prefix[] = "http://"; + const char https_prefix[] = "https://"; + for (size_t i = 0; i < sizeof(http_prefix) - 1; i++) { + if (url[i] != http_prefix[i]) { + return -1; + } + } + + size_t suffix_len = strlen8(url + sizeof(http_prefix) - 1); + if ((sizeof(https_prefix) - 1) + suffix_len + 1 > cap) { + return -1; + } + size_t pos = 0; + for (size_t i = 0; i < sizeof(https_prefix) - 1; i++) { + out[pos++] = (uint8_t)https_prefix[i]; + } + for (size_t i = 0; i < suffix_len; i++) { + out[pos++] = (uint8_t)url[(sizeof(http_prefix) - 1) + i]; + } + out[pos] = 0; + return 0; +} + +static void noop_event(efi_event_t event, void *context) { + (void)event; + (void)context; +} + +static efi_status_t poll_http(efi_http_protocol_t *http, efi_http_token_t *token) { + volatile efi_status_t *token_status = &token->status; + for (uint32_t i = 0; i < HTTP_POLL_LIMIT; i++) { + if (*token_status != EFI_NOT_READY) { + return *token_status; + } + http->poll(http); + } + return *token_status; +} + +static void warm_up_http(efi_boot_services_t *bs, efi_http_protocol_t *http) { + efi_status_t last_poll = EFI_NOT_READY; + for (uint32_t i = 0; i < 20; i++) { + if (bs->stall) { + bs->stall(100000); + } + last_poll = http->poll(http); + } + write_status("http_post_configure_poll_status: ", last_poll); +} + +static efi_status_t locate_protocol_handles(efi_boot_services_t *bs, + const efi_guid_t *guid, + efi_uintn_t *count, + efi_handle_t **handles) { + *count = 0; + *handles = 0; + return bs->locate_handle_buffer(EFI_LOCATE_BY_PROTOCOL, guid, 0, count, handles); +} + +static void print_protocol_handle_count(efi_boot_services_t *bs, + const char *label, + const efi_guid_t *guid) { + efi_uintn_t count = 0; + efi_handle_t *handles = 0; + efi_status_t status = locate_protocol_handles(bs, guid, &count, &handles); + write_ascii(label); + write_ascii("_status: "); + write_ascii("0x"); + write_hex64(status); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_handle_count: "); + write_dec(count); + write_ascii("\r\n"); + if (!is_error(status) && handles) { + bs->free_pool(handles); + } +} + +static void configure_tls_ca(efi_boot_services_t *bs) { + efi_uintn_t service_count = 0; + efi_handle_t *service_handles = 0; + efi_status_t status = locate_protocol_handles(bs, + &efi_tls_service_binding_protocol_guid, + &service_count, + &service_handles); + write_status("tls_config_service_status: ", status); + write_ascii("tls_config_service_handle_count: "); + write_dec(service_count); + write_ascii("\r\n"); + if (is_error(status) || service_count == 0 || !service_handles) { + return; + } + + efi_service_binding_protocol_t *binding = 0; + status = bs->handle_protocol(service_handles[0], + &efi_tls_service_binding_protocol_guid, + (void **)&binding); + write_status("tls_config_binding_open_status: ", status); + if (is_error(status) || !binding) { + bs->free_pool(service_handles); + return; + } + + efi_handle_t child = 0; + status = binding->create_child(binding, &child); + write_status("tls_config_create_child_status: ", status); + if (is_error(status) || !child) { + bs->free_pool(service_handles); + return; + } + + efi_tls_configuration_protocol_t *tls_config = 0; + status = bs->handle_protocol(child, + &efi_tls_configuration_protocol_guid, + (void **)&tls_config); + write_status("tls_config_protocol_status: ", status); + if (!is_error(status) && tls_config) { + efi_uintn_t ca_size = 0; + efi_status_t get_status = tls_config->get_data(tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + 0, + &ca_size); + write_status("tls_config_get_ca_status: ", get_status); + write_ascii("tls_config_get_ca_size: "); + write_dec(ca_size); + write_ascii("\r\n"); + + status = tls_config->set_data(tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + g_https_ca_pem, + (efi_uintn_t)strlen8(g_https_ca_pem)); + write_status("tls_config_set_ca_status: ", status); + + ca_size = 0; + get_status = tls_config->get_data(tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + 0, + &ca_size); + write_status("tls_config_get_ca_after_status: ", get_status); + write_ascii("tls_config_get_ca_after_size: "); + write_dec(ca_size); + write_ascii("\r\n"); + } + + status = binding->destroy_child(binding, child); + write_status("tls_config_destroy_child_status: ", status); + bs->free_pool(service_handles); +} + +static efi_status_t configure_http(efi_http_protocol_t *http) { + static efi_httpv4_access_point_t ipv4; + static efi_http_config_data_t config; + memset8(&ipv4, 0, sizeof(ipv4)); + memset8(&config, 0, sizeof(config)); + ipv4.use_default_address = 1; + config.http_version = HTTP_VERSION_11; + config.timeout_millisec = 0; + config.local_address_is_ipv6 = 0; + config.access_point.ipv4_node = &ipv4; + return http->configure(http, &config); +} + +static efi_status_t http_request(efi_boot_services_t *bs, + efi_http_protocol_t *http, + const char *url, + const char *label) { + static efi_char16_t url16[URL16_MAX]; + if (write_utf16_url(url, url16, URL16_MAX) != 0) { + return EFI_BUFFER_TOO_SMALL; + } + + efi_event_t event = 0; + efi_status_t status = bs->create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, noop_event, 0, &event); + write_ascii(label); + write_ascii("_request_event_status: "); + write_ascii("0x"); + write_hex64(status); + write_ascii("\r\n"); + if (is_error(status)) { + return status; + } + + efi_http_request_data_t request_data; + request_data.method = HTTP_METHOD_GET; + request_data.url = url16; + efi_http_message_t message; + memset8(&message, 0, sizeof(message)); + message.data.request = &request_data; + efi_http_token_t token; + token.event = event; + token.status = EFI_NOT_READY; + token.message = &message; + + efi_status_t submit_status = http->request(http, &token); + write_ascii(label); + write_ascii("_request_submit_status: "); + write_ascii("0x"); + write_hex64(submit_status); + write_ascii("\r\n"); + status = submit_status; + if (!is_error(submit_status)) { + status = poll_http(http, &token); + } + write_ascii(label); + write_ascii("_request_token_status: "); + write_ascii("0x"); + write_hex64(token.status); + write_ascii("\r\n"); + bs->close_event(event); + return status; +} + +static efi_status_t https_request_probe(efi_boot_services_t *bs, + efi_http_protocol_t *http, + const char *url) { + static efi_char16_t url16[URL16_MAX]; + if (write_https_probe_url(url, url16, URL16_MAX) != 0) { + write_ascii("https_probe_url_status: unavailable\r\n"); + return EFI_UNSUPPORTED; + } + + efi_event_t event = 0; + efi_status_t status = bs->create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, noop_event, 0, &event); + write_status("https_probe_event_status: ", status); + if (is_error(status)) { + return status; + } + + efi_http_request_data_t request_data; + request_data.method = HTTP_METHOD_GET; + request_data.url = url16; + efi_http_message_t message; + memset8(&message, 0, sizeof(message)); + message.data.request = &request_data; + efi_http_token_t token; + token.event = event; + token.status = EFI_NOT_READY; + token.message = &message; + + efi_status_t submit_status = http->request(http, &token); + write_status("https_probe_submit_status: ", submit_status); + write_status("https_probe_token_status: ", token.status); + bs->close_event(event); + return submit_status; +} + +static efi_status_t http_response(efi_boot_services_t *bs, + efi_http_protocol_t *http, + void *body, + size_t *body_len, + uint32_t *http_status) { + efi_event_t event = 0; + efi_status_t status = bs->create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, noop_event, 0, &event); + if (is_error(status)) { + return status; + } + + efi_http_response_data_t response_data; + response_data.status_code = 0; + efi_http_message_t message; + memset8(&message, 0, sizeof(message)); + message.data.response = &response_data; + message.body_length = *body_len; + message.body = body; + + efi_http_token_t token; + token.event = event; + token.status = EFI_NOT_READY; + token.message = &message; + + status = http->response(http, &token); + if (!is_error(status)) { + status = poll_http(http, &token); + } + *body_len = message.body_length; + *http_status = response_data.status_code; + if (message.headers) { + bs->free_pool(message.headers); + } + bs->close_event(event); + return status; +} + +static const char *find_key(const char *json, const char *key) { + size_t key_len = strlen8(key); + for (const char *p = json; *p; p++) { + if (*p != '"') { + continue; + } + size_t i = 0; + while (i < key_len && p[1 + i] == key[i]) { + i++; + } + if (i == key_len && p[1 + i] == '"') { + const char *q = p + 2 + key_len; + while (*q == ' ' || *q == '\r' || *q == '\n' || *q == '\t') { + q++; + } + if (*q == ':') { + return q + 1; + } + } + } + return 0; +} + +static int json_string(const char *json, const char *key, char *out, size_t cap) { + const char *p = find_key(json, key); + if (!p) { + return -1; + } + while (*p == ' ' || *p == '\r' || *p == '\n' || *p == '\t') { + p++; + } + if (*p != '"') { + return -1; + } + p++; + size_t n = 0; + while (*p && *p != '"') { + if (*p == '\\' || n + 1 >= cap) { + return -1; + } + out[n++] = *p++; + } + if (*p != '"') { + return -1; + } + out[n] = '\0'; + return 0; +} + +static int parse_u64(const char *s, uint64_t *out) { + uint64_t value = 0; + int radix = 10; + int saw = 0; + if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { + radix = 16; + s += 2; + } + while (*s) { + if (*s == '_') { + s++; + continue; + } + uint8_t digit; + if (*s >= '0' && *s <= '9') { + digit = (uint8_t)(*s - '0'); + } else if (*s >= 'a' && *s <= 'f') { + digit = (uint8_t)(*s - 'a' + 10); + } else if (*s >= 'A' && *s <= 'F') { + digit = (uint8_t)(*s - 'A' + 10); + } else { + break; + } + if (digit >= radix) { + return -1; + } + value = value * (uint64_t)radix + digit; + saw = 1; + s++; + } + if (!saw) { + return -1; + } + *out = value; + return 0; +} + +static int json_u64(const char *json, const char *key, uint64_t *out) { + const char *p = find_key(json, key); + if (!p) { + return -1; + } + while (*p == ' ' || *p == '\r' || *p == '\n' || *p == '\t') { + p++; + } + return parse_u64(p, out); +} + +static int json_addr_string(const char *json, const char *key, uint64_t *out) { + char buf[64]; + if (json_string(json, key, buf, sizeof(buf)) != 0) { + return -1; + } + return parse_u64(buf, out); +} + +static int parse_manifest(const char *json, manifest_t *manifest) { + if (json_string(json, "kernel_url", manifest->kernel_url, sizeof(manifest->kernel_url)) != 0) { + return -1; + } + if (json_u64(json, "kernel_size", &manifest->kernel_size) != 0) { + return -1; + } + if (json_addr_string(json, "kernel_load_addr", &manifest->kernel_load_addr) != 0) { + return -1; + } + if (json_addr_string(json, "entry_point", &manifest->entry_point) != 0) { + return -1; + } + if (json_string(json, "arch", manifest->arch, sizeof(manifest->arch)) != 0) { + return -1; + } + return 0; +} + +static efi_uintn_t page_count(uint64_t addr, uint64_t size) { + (void)addr; + return (efi_uintn_t)((size + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE); +} + +static efi_status_t download_kernel(efi_boot_services_t *bs, + efi_http_protocol_t *http, + const manifest_t *manifest, + efi_uintn_t *pages_out) { + if (manifest->kernel_size == 0 || manifest->kernel_size > MAX_KERNEL_SIZE) { + return EFI_UNSUPPORTED; + } + if ((manifest->kernel_load_addr % EFI_PAGE_SIZE) != 0) { + return EFI_UNSUPPORTED; + } + + efi_uintn_t pages = page_count(manifest->kernel_load_addr, manifest->kernel_size); + efi_physical_address_t target = manifest->kernel_load_addr; + efi_status_t status = bs->allocate_pages(EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, pages, &target); + write_status("kernel_allocate_pages_status: ", status); + write_ascii("kernel_target_addr: 0x"); + write_hex64(target); + write_ascii("\r\n"); + if (is_error(status) || target != manifest->kernel_load_addr) { + return status; + } + + status = http_request(bs, http, manifest->kernel_url, "kernel"); + write_status("kernel_request_completion: ", status); + if (is_error(status)) { + bs->free_pages(target, pages); + return status; + } + + uint64_t downloaded = 0; + uint32_t checksum = 0; + while (downloaded < manifest->kernel_size) { + size_t remaining = (size_t)(manifest->kernel_size - downloaded); + size_t body_len = remaining < KERNEL_CHUNK ? remaining : KERNEL_CHUNK; + uint32_t http_status = 0; + uint8_t *dst = (uint8_t *)(uintptr_t)(manifest->kernel_load_addr + downloaded); + status = http_response(bs, http, dst, &body_len, &http_status); + if (is_error(status) || http_status != HTTP_STATUS_200_OK || body_len == 0) { + write_status("kernel_response_completion: ", status); + write_ascii("kernel_response_status_enum: "); + write_dec(http_status); + write_ascii("\r\n"); + bs->free_pages(target, pages); + return is_error(status) ? status : EFI_DEVICE_ERROR; + } + for (size_t i = 0; i < body_len; i++) { + checksum += dst[i]; + } + downloaded += body_len; + } + + write_ascii("kernel_downloaded_size: "); + write_dec(downloaded); + write_ascii("\r\n"); + write_ascii("kernel_expected_size: "); + write_dec(manifest->kernel_size); + write_ascii("\r\n"); + write_ascii("kernel_checksum32: 0x"); + write_hex64(checksum); + write_ascii("\r\n"); + *pages_out = pages; + return EFI_SUCCESS; +} + +static efi_status_t print_memory_map(efi_boot_services_t *bs, efi_uintn_t *map_key_out) { + static uint8_t memory_map[MEMORY_MAP_MAX]; + efi_uintn_t map_size = sizeof(memory_map); + efi_uintn_t descriptor_size = 0; + uint32_t descriptor_version = 0; + efi_status_t status = bs->get_memory_map(&map_size, + (efi_memory_descriptor_t *)memory_map, + map_key_out, + &descriptor_size, + &descriptor_version); + write_status("memory_map_status: ", status); + write_ascii("memory_map_size: "); + write_dec(map_size); + write_ascii("\r\n"); + write_ascii("memory_map_key: "); + write_dec(*map_key_out); + write_ascii("\r\n"); + write_ascii("memory_map_descriptor_size: "); + write_dec(descriptor_size); + write_ascii("\r\n"); + return status; +} + +static void call_kernel(uint64_t entry_point) { + void (*entry)(void) = (void (*)(void))(uintptr_t)entry_point; + entry(); + for (;;) { + } +} + +static efi_status_t try_http_service_handle(efi_handle_t image, + efi_boot_services_t *bs, + efi_handle_t service_handle, + efi_uintn_t index) { + write_ascii("http_service_binding_try_index: "); + write_dec(index); + write_ascii("\r\n"); + efi_service_binding_protocol_t *binding = 0; + efi_status_t status = bs->handle_protocol(service_handle, + &efi_http_service_binding_protocol_guid, + (void **)&binding); + write_status("http_service_binding_open_status: ", status); + if (is_error(status) || !binding) { + return is_error(status) ? status : EFI_UNSUPPORTED; + } + + efi_handle_t child = 0; + status = binding->create_child(binding, &child); + write_status("http_create_child_status: ", status); + if (is_error(status) || !child) { + return is_error(status) ? status : EFI_UNSUPPORTED; + } + + efi_http_protocol_t *http = 0; + status = bs->handle_protocol(child, &efi_http_protocol_guid, (void **)&http); + write_status("http_child_protocol_status: ", status); + if (is_error(status) || !http) { + binding->destroy_child(binding, child); + return is_error(status) ? status : EFI_UNSUPPORTED; + } + + status = configure_http(http); + write_status("http_configure_status: ", status); + if (is_error(status)) { + binding->destroy_child(binding, child); + return status; + } + warm_up_http(bs, http); + + static char manifest_body[MANIFEST_MAX + 1]; + status = http_request(bs, http, OSTOOL_MANIFEST_URL, "manifest"); + write_status("manifest_request_completion: ", status); + if (is_error(status)) { + if (status == EFI_ACCESS_DENIED) { + https_request_probe(bs, http, OSTOOL_MANIFEST_URL); + } + binding->destroy_child(binding, child); + return status; + } + + size_t body_len = MANIFEST_MAX; + uint32_t http_status = 0; + status = http_response(bs, http, manifest_body, &body_len, &http_status); + write_status("manifest_response_completion: ", status); + write_ascii("manifest_response_status_enum: "); + write_dec(http_status); + write_ascii("\r\n"); + write_ascii("manifest_response_body_length: "); + write_dec(body_len); + write_ascii("\r\n"); + if (is_error(status) || http_status != HTTP_STATUS_200_OK || body_len >= sizeof(manifest_body)) { + binding->destroy_child(binding, child); + return is_error(status) ? status : EFI_DEVICE_ERROR; + } + manifest_body[body_len] = '\0'; + + manifest_t manifest; + memset8(&manifest, 0, sizeof(manifest)); + if (parse_manifest(manifest_body, &manifest) != 0) { + write_ascii("manifest_parse_failed\r\n"); + binding->destroy_child(binding, child); + return EFI_DEVICE_ERROR; + } + + write_ascii("manifest_arch: "); + write_ascii(manifest.arch); + write_ascii("\r\n"); + write_ascii("manifest_kernel_url: "); + write_ascii(manifest.kernel_url); + write_ascii("\r\n"); + write_ascii("manifest_kernel_size: "); + write_dec(manifest.kernel_size); + write_ascii("\r\n"); + write_ascii("manifest_kernel_load_addr: 0x"); + write_hex64(manifest.kernel_load_addr); + write_ascii("\r\n"); + write_ascii("manifest_entry_point: 0x"); + write_hex64(manifest.entry_point); + write_ascii("\r\n"); + + efi_uintn_t kernel_pages = 0; + status = download_kernel(bs, http, &manifest, &kernel_pages); + write_status("kernel_download_status: ", status); + if (is_error(status)) { + binding->destroy_child(binding, child); + return status; + } + + efi_uintn_t map_key = 0; + status = print_memory_map(bs, &map_key); + write_ascii("boot_jump_enabled: "); + write_ascii(OSTOOL_ENABLE_BOOT_JUMP ? "yes\r\n" : "no\r\n"); + if (!OSTOOL_ENABLE_BOOT_JUMP || is_error(status)) { + write_ascii("jump_skipped: boot jump disabled\r\n"); + binding->destroy_child(binding, child); + return EFI_SUCCESS; + } + + status = bs->exit_boot_services(image, map_key); + if (!is_error(status)) { + call_kernel(manifest.entry_point); + } + write_status("exit_boot_services_status: ", status); + write_ascii("jump_failed\r\n"); + (void)kernel_pages; + binding->destroy_child(binding, child); + return EFI_SUCCESS; +} + +efi_status_t efi_main(efi_handle_t image, efi_system_table_t *system_table) { + g_console = system_table ? system_table->con_out : 0; + write_ascii("ostool LoongArch64 UEFI loader\r\n"); + write_ascii("manifest_url: "); + write_ascii(OSTOOL_MANIFEST_URL); + write_ascii("\r\n"); + + efi_boot_services_t *bs = system_table->boot_services; + print_protocol_handle_count(bs, "tls_service_binding", &efi_tls_service_binding_protocol_guid); + print_protocol_handle_count(bs, "tcp4_service_binding", &efi_tcp4_service_binding_protocol_guid); + configure_tls_ca(bs); + + efi_uintn_t service_count = 0; + efi_handle_t *service_handles = 0; + efi_status_t status = locate_protocol_handles(bs, + &efi_http_service_binding_protocol_guid, + &service_count, + &service_handles); + write_status("http_service_binding_status: ", status); + write_ascii("http_service_binding_handle_count: "); + write_dec(service_count); + write_ascii("\r\n"); + if (is_error(status) || service_count == 0 || !service_handles) { + return EFI_SUCCESS; + } + + for (efi_uintn_t i = 0; i < service_count; i++) { + status = try_http_service_handle(image, bs, service_handles[i], i); + write_status("http_service_binding_try_status: ", status); + if (!is_error(status)) { + break; + } + } + bs->free_pool(service_handles); + return EFI_SUCCESS; +} diff --git a/loongarch64-uefi-loader/loader.lds b/loongarch64-uefi-loader/loader.lds new file mode 100644 index 00000000..68076396 --- /dev/null +++ b/loongarch64-uefi-loader/loader.lds @@ -0,0 +1,47 @@ +OUTPUT_FORMAT("elf64-loongarch") +OUTPUT_ARCH(loongarch) +ENTRY(efi_main) + +SECTIONS +{ + . = 0x1000; + + .text ALIGN(4096) : { + *(.text.efi_main) + *(.text .text.*) + } + + .rodata ALIGN(4096) : { + *(.srodata .srodata.*) + *(.rodata .rodata.*) + } + + .data ALIGN(4096) : { + *(.sdata .sdata.*) + *(.data .data.*) + } + + .bss ALIGN(4096) (NOLOAD) : { + __bss_start = .; + *(.sbss .sbss.*) + *(.bss .bss.*) + *(COMMON) + __bss_end = .; + } + + .reloc ALIGN(4096) : { + LONG(0); + LONG(12); + SHORT(0); + SHORT(0); + } + + /DISCARD/ : { + *(.comment) + *(.note*) + *(.eh_frame*) + *(.interp) + *(.dyn*) + *(.gnu*) + } +} diff --git a/loongarch64-uefi-loader/src/main.rs b/loongarch64-uefi-loader/src/main.rs new file mode 100644 index 00000000..673959a8 --- /dev/null +++ b/loongarch64-uefi-loader/src/main.rs @@ -0,0 +1,1742 @@ +#![no_std] +#![no_main] + +use core::ffi::c_void; +use core::panic::PanicInfo; +use core::ptr::{null_mut, read_volatile}; + +const OSTOOL_MANIFEST_URL: &str = env!("OSTOOL_MANIFEST_URL"); +const OSTOOL_ENABLE_BOOT_JUMP: bool = cfg!(ostool_enable_boot_jump); + +type EfiPhysicalAddress = u64; +type EfiVirtualAddress = u64; +type EfiHandle = *mut c_void; +type EfiEvent = *mut c_void; +type EfiTpl = usize; +type EfiMemoryType = u32; +type EfiAllocateType = u32; +type EfiLocateSearchType = u32; + +#[repr(transparent)] +#[derive(Clone, Copy, PartialEq, Eq)] +struct EfiStatus(u64); + +const EFI_SUCCESS: EfiStatus = EfiStatus(0); +const EFI_ERROR_BIT: u64 = 1 << 63; +const EFI_UNSUPPORTED: EfiStatus = EfiStatus(EFI_ERROR_BIT | 3); +const EFI_BUFFER_TOO_SMALL: EfiStatus = EfiStatus(EFI_ERROR_BIT | 5); +const EFI_NOT_READY: EfiStatus = EfiStatus(EFI_ERROR_BIT | 6); +const EFI_DEVICE_ERROR: EfiStatus = EfiStatus(EFI_ERROR_BIT | 7); +const EFI_NOT_FOUND: EfiStatus = EfiStatus(EFI_ERROR_BIT | 14); + +const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 0; +const EFI_LOADER_DATA: EfiMemoryType = 2; +const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; +const EVT_NOTIFY_SIGNAL: u32 = 0x0000_0200; +const TPL_CALLBACK: EfiTpl = 8; +const EFI_PAGE_SIZE: usize = 4096; + +const HTTP_VERSION_11: u32 = 1; +const HTTP_METHOD_GET: u32 = 0; +const HTTP_STATUS_200_OK: u32 = 3; + +const MANIFEST_MAX: usize = 4096; +const URL16_MAX: usize = 1024; +const KERNEL_CHUNK: usize = 16 * 1024; +const MAX_KERNEL_SIZE: u64 = 256 * 1024 * 1024; +const MEMORY_MAP_MAX: usize = 64 * 1024; +const HTTP_POLL_LIMIT: usize = 1_000_000; + +const EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE: u32 = 2; + +#[repr(C)] +#[derive(Clone, Copy)] +struct EfiGuid { + data1: u32, + data2: u16, + data3: u16, + data4: [u8; 8], +} + +#[repr(C)] +struct EfiTableHeader { + signature: u64, + revision: u32, + header_size: u32, + crc32: u32, + reserved: u32, +} + +#[repr(C)] +struct EfiSimpleTextOutputProtocol { + reset: usize, + output_string: extern "C" fn(*mut EfiSimpleTextOutputProtocol, *const u16) -> EfiStatus, +} + +#[repr(C)] +struct EfiMemoryDescriptor { + memory_type: u32, + physical_start: EfiPhysicalAddress, + virtual_start: EfiVirtualAddress, + number_of_pages: u64, + attribute: u64, +} + +#[repr(C)] +struct EfiBootServices { + hdr: EfiTableHeader, + raise_tpl: usize, + restore_tpl: usize, + allocate_pages: + extern "C" fn(EfiAllocateType, EfiMemoryType, usize, *mut EfiPhysicalAddress) -> EfiStatus, + free_pages: extern "C" fn(EfiPhysicalAddress, usize) -> EfiStatus, + get_memory_map: extern "C" fn( + *mut usize, + *mut EfiMemoryDescriptor, + *mut usize, + *mut usize, + *mut u32, + ) -> EfiStatus, + allocate_pool: extern "C" fn(EfiMemoryType, usize, *mut *mut c_void) -> EfiStatus, + free_pool: extern "C" fn(*mut c_void) -> EfiStatus, + create_event: extern "C" fn( + u32, + EfiTpl, + Option, + *mut c_void, + *mut EfiEvent, + ) -> EfiStatus, + set_timer: usize, + wait_for_event: usize, + signal_event: usize, + close_event: extern "C" fn(EfiEvent) -> EfiStatus, + check_event: usize, + install_protocol_interface: usize, + reinstall_protocol_interface: usize, + uninstall_protocol_interface: usize, + handle_protocol: extern "C" fn(EfiHandle, *const EfiGuid, *mut *mut c_void) -> EfiStatus, + reserved: usize, + register_protocol_notify: usize, + locate_handle: usize, + locate_device_path: usize, + install_configuration_table: usize, + load_image: usize, + start_image: usize, + exit: usize, + unload_image: usize, + exit_boot_services: extern "C" fn(EfiHandle, usize) -> EfiStatus, + get_next_monotonic_count: usize, + stall: Option EfiStatus>, + set_watchdog_timer: usize, + connect_controller: usize, + disconnect_controller: usize, + open_protocol: usize, + close_protocol: usize, + open_protocol_information: usize, + protocols_per_handle: usize, + locate_handle_buffer: extern "C" fn( + EfiLocateSearchType, + *const EfiGuid, + *mut c_void, + *mut usize, + *mut *mut EfiHandle, + ) -> EfiStatus, +} + +#[repr(C)] +struct EfiSystemTable { + hdr: EfiTableHeader, + firmware_vendor: *mut u16, + firmware_revision: u32, + console_in_handle: EfiHandle, + con_in: *mut c_void, + console_out_handle: EfiHandle, + con_out: *mut EfiSimpleTextOutputProtocol, + standard_error_handle: EfiHandle, + std_err: *mut EfiSimpleTextOutputProtocol, + runtime_services: *mut c_void, + boot_services: *mut EfiBootServices, +} + +#[repr(C)] +struct EfiServiceBindingProtocol { + create_child: extern "C" fn(*mut EfiServiceBindingProtocol, *mut EfiHandle) -> EfiStatus, + destroy_child: extern "C" fn(*mut EfiServiceBindingProtocol, EfiHandle) -> EfiStatus, +} + +#[repr(C)] +union EfiHttpConfigAccessPoint { + ipv4_node: *mut EfiHttpv4AccessPoint, + ipv6_node: *mut c_void, +} + +#[repr(C)] +struct EfiHttpv4AccessPoint { + use_default_address: u8, + local_address: [u8; 4], + local_subnet: [u8; 4], + local_port: u16, +} + +#[repr(C)] +struct EfiHttpConfigData { + http_version: u32, + timeout_millisec: u32, + local_address_is_ipv6: u8, + padding: [u8; 7], + access_point: EfiHttpConfigAccessPoint, +} + +#[repr(C)] +struct EfiHttpRequestData { + method: u32, + url: *mut u16, +} + +#[repr(C)] +struct EfiHttpResponseData { + status_code: u32, +} + +#[repr(C)] +union EfiHttpMessageData { + request: *mut EfiHttpRequestData, + response: *mut EfiHttpResponseData, +} + +#[repr(C)] +struct EfiHttpHeader { + field_name: *mut u8, + field_value: *mut u8, +} + +#[repr(C)] +struct EfiHttpMessage { + data: EfiHttpMessageData, + header_count: usize, + headers: *mut EfiHttpHeader, + body_length: usize, + body: *mut c_void, +} + +#[repr(C)] +struct EfiHttpToken { + event: EfiEvent, + status: EfiStatus, + message: *mut EfiHttpMessage, +} + +#[repr(C)] +struct EfiHttpProtocol { + get_mode_data: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpConfigData) -> EfiStatus, + configure: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpConfigData) -> EfiStatus, + request: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpToken) -> EfiStatus, + cancel: usize, + response: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpToken) -> EfiStatus, + poll: extern "C" fn(*mut EfiHttpProtocol) -> EfiStatus, +} + +#[repr(C)] +struct EfiTlsConfigurationProtocol { + set_data: extern "C" fn(*mut EfiTlsConfigurationProtocol, u32, *mut c_void, usize) -> EfiStatus, + get_data: + extern "C" fn(*mut EfiTlsConfigurationProtocol, u32, *mut c_void, *mut usize) -> EfiStatus, +} + +#[derive(Clone, Copy)] +struct Manifest { + kernel_url: [u8; 1024], + kernel_url_len: usize, + kernel_size: u64, + kernel_load_addr: u64, + entry_point: u64, + arch: [u8; 32], + arch_len: usize, +} + +const EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0xbdc8e6af, + data2: 0xd9bc, + data3: 0x4379, + data4: [0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c], +}; + +const EFI_HTTP_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x7a59b29b, + data2: 0x910b, + data3: 0x4171, + data4: [0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b], +}; + +const EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x952cb795, + data2: 0xff36, + data3: 0x48cf, + data4: [0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d], +}; + +const EFI_TLS_CONFIGURATION_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x1682fe44, + data2: 0xbd7a, + data3: 0x4407, + data4: [0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d], +}; + +const EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x00720665, + data2: 0x67eb, + data3: 0x4a99, + data4: [0xba, 0xf7, 0xd3, 0xc3, 0x3a, 0x1c, 0x7c, 0xc9], +}; + +static HTTPS_CA_PEM: &[u8] = b"-----BEGIN CERTIFICATE-----\n\ +MIIDHjCCAgagAwIBAgIUBJubHQIousJm3ZT9sNPYq0u1AhwwDQYJKoZIhvcNAQEL\n\ +BQAwFjEUMBIGA1UEAwwLMTAuMy4xMC4yMjkwHhcNMjYwNTEzMDkxMTIwWhcNMjYw\n\ +NTIwMDkxMTIwWjAWMRQwEgYDVQQDDAsxMC4zLjEwLjIyOTCCASIwDQYJKoZIhvcN\n\ +AQEBBQADggEPADCCAQoCggEBALb3klUcff8fXYIcsgeQr1gs2rnwbOl/4Unwtulx\n\ +wG1K8joXYwWT4NP4XSOJy8aVuLk0FSd8VB29l6gjduSYzdC1CE9i3bzJnu4E96X/\n\ +EqRWP6QPkQJUizpH3qwxK1sDNJTmoAdq48v3cLgyyDdxzU/iVlWM51izk4njFMzZ\n\ +4PCLFfznANnj8o5diDCQ96uyKxmaXArIeDAAwcTSlJYc7QHWg6WEg+FQcn3TaMKJ\n\ +8rNELrKMrygc71ZdF9r6anud4YMouse6wJmEzGEVSCQ/y3dxd8gr1Ixq3DV9Yj9J\n\ +fZ57GWjWLTi1CWyMAAod8b6xr+o2yHRS2mGIfTEskTHTc+8CAwEAAaNkMGIwHQYD\n\ +VR0OBBYEFIimL7eY9PEocEUee1gz/YxTalmbMB8GA1UdIwQYMBaAFIimL7eY9PEo\n\ +cEUee1gz/YxTalmbMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0RBAgwBocECgMK5TAN\n\ +BgkqhkiG9w0BAQsFAAOCAQEAf1TkdDogQAYDgSUdraZ6WtOrD7MrLH69DZIcMrVf\n\ +GymOgar70uD9s1MEAwAsCgfqN8+kRcR/viWY8e86AzYVralqiLVs9tpR+vrnFejd\n\ +f9KLftc3owFwmiMLR5szwZMENOz2F+TJ8fNZBTXaJuITxrcIwuBym0FqL1pkN4hL\n\ +ikfU5paqfDst5LA/Wu/56XPtP8tFGh498jNsKlAumlQgaX0w+xxGiaGf1WkvTOP8\n\ +bVwyUYVeTIG2utpOKra0gkg42qcPdvRzZsT9REzlp2cxyBx5fkSmS0kXtqg4fT69\n\ +9/dZPxTWismXdZ4HN74kKak5tAB9CwKXvwaLRqOmXEg4hw==\n\ +-----END CERTIFICATE-----\n"; + +static mut CONSOLE: *mut EfiSimpleTextOutputProtocol = null_mut(); +static mut MEMORY_MAP: [u8; MEMORY_MAP_MAX] = [0; MEMORY_MAP_MAX]; + +impl EfiStatus { + fn is_error(self) -> bool { + (self.0 & EFI_ERROR_BIT) != 0 + } +} + +fn console() -> *mut EfiSimpleTextOutputProtocol { + unsafe { CONSOLE } +} + +fn write_ascii(s: &str) { + write_bytes(s.as_bytes()); +} + +fn write_bytes(s: &[u8]) { + let out = console(); + if out.is_null() { + return; + } + let mut pos = 0; + while pos < s.len() { + let mut buf = [0u16; 256]; + let mut n = 0; + while pos + n < s.len() && n + 1 < buf.len() { + buf[n] = s[pos + n] as u16; + n += 1; + } + buf[n] = 0; + unsafe { + ((*out).output_string)(out, buf.as_ptr()); + } + pos += n; + } +} + +fn write_hex64(value: u64) { + let mut out = [0u8; 16]; + let mut i = 0; + while i < 16 { + let digit = ((value >> ((15 - i) * 4)) & 0xf) as u8; + out[i] = if digit < 10 { + b'0' + digit + } else { + b'a' + digit - 10 + }; + i += 1; + } + write_bytes(&out); +} + +fn write_dec(mut value: u64) { + let mut out = [0u8; 32]; + let mut pos = out.len(); + if value == 0 { + write_ascii("0"); + return; + } + while value > 0 && pos > 0 { + pos -= 1; + out[pos] = b'0' + (value % 10) as u8; + value /= 10; + } + write_bytes(&out[pos..]); +} + +fn write_status(label: &str, status: EfiStatus) { + write_ascii(label); + write_ascii("0x"); + write_hex64(status.0); + write_ascii("\r\n"); +} + +fn write_utf16_url(url: &[u8], out: &mut [u16]) -> Result<*mut u16, EfiStatus> { + if url.len() + 1 > out.len() { + return Err(EFI_BUFFER_TOO_SMALL); + } + let mut i = 0; + while i < url.len() { + out[i] = url[i] as u16; + i += 1; + } + out[i] = 0; + Ok(out.as_mut_ptr()) +} + +extern "C" fn noop_event(_event: EfiEvent, _context: *mut c_void) {} + +fn poll_http(http: *mut EfiHttpProtocol, token: *const EfiHttpToken) -> EfiStatus { + let mut i = 0; + while i < HTTP_POLL_LIMIT { + let status = unsafe { read_volatile(core::ptr::addr_of!((*token).status)) }; + if status != EFI_NOT_READY { + return status; + } + unsafe { + ((*http).poll)(http); + } + i += 1; + } + unsafe { read_volatile(core::ptr::addr_of!((*token).status)) } +} + +fn warm_up_http(bs: *mut EfiBootServices, http: *mut EfiHttpProtocol) { + let mut last_poll = EFI_NOT_READY; + let mut i = 0; + while i < 20 { + unsafe { + if let Some(stall) = (*bs).stall { + stall(100_000); + } + last_poll = ((*http).poll)(http); + } + i += 1; + } + write_status("http_post_configure_poll_status: ", last_poll); +} + +fn locate_protocol_handles( + bs: *mut EfiBootServices, + guid: &EfiGuid, + count: &mut usize, + handles: &mut *mut EfiHandle, +) -> EfiStatus { + *count = 0; + *handles = null_mut(); + unsafe { + ((*bs).locate_handle_buffer)( + EFI_LOCATE_BY_PROTOCOL, + guid as *const EfiGuid, + null_mut(), + count, + handles, + ) + } +} + +fn print_protocol_handle_count(bs: *mut EfiBootServices, label: &str, guid: &EfiGuid) { + let mut count = 0usize; + let mut handles = null_mut(); + let status = locate_protocol_handles(bs, guid, &mut count, &mut handles); + write_ascii(label); + write_ascii("_status: "); + write_ascii("0x"); + write_hex64(status.0); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_handle_count: "); + write_dec(count as u64); + write_ascii("\r\n"); + if !status.is_error() && !handles.is_null() { + unsafe { + ((*bs).free_pool)(handles as *mut c_void); + } + } +} + +fn open_protocol( + bs: *mut EfiBootServices, + handle: EfiHandle, + guid: &EfiGuid, +) -> Result<*mut T, EfiStatus> { + let mut interface = null_mut(); + let status = unsafe { ((*bs).handle_protocol)(handle, guid as *const EfiGuid, &mut interface) }; + if status.is_error() || interface.is_null() { + return Err(if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }); + } + Ok(interface as *mut T) +} + +fn b64_value(ch: u8) -> Option { + match ch { + b'A'..=b'Z' => Some(ch - b'A'), + b'a'..=b'z' => Some(ch - b'a' + 26), + b'0'..=b'9' => Some(ch - b'0' + 52), + b'+' => Some(62), + b'/' => Some(63), + _ => None, + } +} + +fn pem_to_der(pem: &[u8], out: &mut [u8]) -> Result { + let mut in_body = false; + let mut accum = 0u32; + let mut bits = 0u32; + let mut len = 0usize; + let mut i = 0usize; + while i < pem.len() { + let ch = pem[i]; + if !in_body { + if ch == b'\n' { + in_body = true; + } + i += 1; + continue; + } + if ch == b'-' { + break; + } + if ch == b'=' { + break; + } + if let Some(value) = b64_value(ch) { + accum = (accum << 6) | value as u32; + bits += 6; + while bits >= 8 { + bits -= 8; + if len >= out.len() { + return Err(EFI_BUFFER_TOO_SMALL); + } + out[len] = ((accum >> bits) & 0xff) as u8; + len += 1; + } + } + i += 1; + } + Ok(len) +} + +fn set_tls_ca_variants(tls_config: *mut EfiTlsConfigurationProtocol, label: &str) { + let set_pem_status = unsafe { + ((*tls_config).set_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + HTTPS_CA_PEM.as_ptr() as *mut c_void, + HTTPS_CA_PEM.len(), + ) + }; + if label == "tls_config" { + write_status("tls_config_set_ca_status: ", set_pem_status); + } else { + write_ascii(label); + write_ascii("_set_ca_pem_status: 0x"); + write_hex64(set_pem_status.0); + write_ascii("\r\n"); + } + + let mut der = [0u8; 1536]; + match pem_to_der(HTTPS_CA_PEM, &mut der) { + Ok(der_len) => { + write_ascii(label); + write_ascii("_ca_der_size: "); + write_dec(der_len as u64); + write_ascii("\r\n"); + let set_der_status = unsafe { + ((*tls_config).set_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + der.as_mut_ptr() as *mut c_void, + der_len, + ) + }; + write_ascii(label); + write_ascii("_set_ca_der_status: 0x"); + write_hex64(set_der_status.0); + write_ascii("\r\n"); + } + Err(status) => { + write_ascii(label); + write_ascii("_ca_der_decode_status: 0x"); + write_hex64(status.0); + write_ascii("\r\n"); + } + } +} + +fn configure_tls_ca(bs: *mut EfiBootServices) { + let mut service_count = 0usize; + let mut service_handles = null_mut(); + let status = locate_protocol_handles( + bs, + &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, + &mut service_count, + &mut service_handles, + ); + write_status("tls_config_service_status: ", status); + write_ascii("tls_config_service_handle_count: "); + write_dec(service_count as u64); + write_ascii("\r\n"); + if status.is_error() || service_count == 0 || service_handles.is_null() { + return; + } + + let service_handle = unsafe { *service_handles }; + let binding = match open_protocol::( + bs, + service_handle, + &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, + ) { + Ok(binding) => { + write_status("tls_config_binding_open_status: ", EFI_SUCCESS); + binding + } + Err(status) => { + write_status("tls_config_binding_open_status: ", status); + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } + return; + } + }; + + let mut child = null_mut(); + let status = unsafe { ((*binding).create_child)(binding, &mut child) }; + write_status("tls_config_create_child_status: ", status); + if status.is_error() || child.is_null() { + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } + return; + } + + match open_protocol::( + bs, + child, + &EFI_TLS_CONFIGURATION_PROTOCOL_GUID, + ) { + Ok(tls_config) => { + write_status("tls_config_protocol_status: ", EFI_SUCCESS); + let mut ca_size = 0usize; + let get_status = unsafe { + ((*tls_config).get_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + null_mut(), + &mut ca_size, + ) + }; + write_status("tls_config_get_ca_status: ", get_status); + write_ascii("tls_config_get_ca_size: "); + write_dec(ca_size as u64); + write_ascii("\r\n"); + + set_tls_ca_variants(tls_config, "tls_config"); + + ca_size = 0; + let get_after_status = unsafe { + ((*tls_config).get_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + null_mut(), + &mut ca_size, + ) + }; + write_status("tls_config_get_ca_after_status: ", get_after_status); + write_ascii("tls_config_get_ca_after_size: "); + write_dec(ca_size as u64); + write_ascii("\r\n"); + } + Err(status) => write_status("tls_config_protocol_status: ", status), + } + + let destroy_status = unsafe { ((*binding).destroy_child)(binding, child) }; + write_status("tls_config_destroy_child_status: ", destroy_status); + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } +} + +fn configure_tls_ca_on_handle(bs: *mut EfiBootServices, handle: EfiHandle, label: &str) { + match open_protocol::( + bs, + handle, + &EFI_TLS_CONFIGURATION_PROTOCOL_GUID, + ) { + Ok(tls_config) => { + write_ascii(label); + write_ascii("_protocol_status: 0x"); + write_hex64(EFI_SUCCESS.0); + write_ascii("\r\n"); + + let mut ca_size = 0usize; + let get_status = unsafe { + ((*tls_config).get_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + null_mut(), + &mut ca_size, + ) + }; + write_ascii(label); + write_ascii("_get_ca_status: 0x"); + write_hex64(get_status.0); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_get_ca_size: "); + write_dec(ca_size as u64); + write_ascii("\r\n"); + + set_tls_ca_variants(tls_config, label); + + ca_size = 0; + let get_after_status = unsafe { + ((*tls_config).get_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + null_mut(), + &mut ca_size, + ) + }; + write_ascii(label); + write_ascii("_get_ca_after_status: 0x"); + write_hex64(get_after_status.0); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_get_ca_after_size: "); + write_dec(ca_size as u64); + write_ascii("\r\n"); + } + Err(status) => { + write_ascii(label); + write_ascii("_protocol_status: 0x"); + write_hex64(status.0); + write_ascii("\r\n"); + } + } +} + +fn configure_http(http: *mut EfiHttpProtocol) -> EfiStatus { + let mut ipv4 = EfiHttpv4AccessPoint { + use_default_address: 1, + local_address: [0; 4], + local_subnet: [0; 4], + local_port: 0, + }; + let mut config = EfiHttpConfigData { + http_version: HTTP_VERSION_11, + timeout_millisec: 0, + local_address_is_ipv6: 0, + padding: [0; 7], + access_point: EfiHttpConfigAccessPoint { + ipv4_node: &mut ipv4, + }, + }; + unsafe { ((*http).configure)(http, &mut config) } +} + +fn print_http_mode_data(http: *mut EfiHttpProtocol, label: &str) { + let mut ipv4 = EfiHttpv4AccessPoint { + use_default_address: 0, + local_address: [0; 4], + local_subnet: [0; 4], + local_port: 0, + }; + let mut config = EfiHttpConfigData { + http_version: 0, + timeout_millisec: 0, + local_address_is_ipv6: 0, + padding: [0; 7], + access_point: EfiHttpConfigAccessPoint { + ipv4_node: &mut ipv4, + }, + }; + let status = unsafe { ((*http).get_mode_data)(http, &mut config) }; + write_ascii(label); + write_ascii("_get_mode_data_status: 0x"); + write_hex64(status.0); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_mode_http_version: "); + write_dec(config.http_version as u64); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_mode_timeout_ms: "); + write_dec(config.timeout_millisec as u64); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_mode_ipv6: "); + write_dec(config.local_address_is_ipv6 as u64); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_mode_ipv4_default: "); + write_dec(ipv4.use_default_address as u64); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_mode_ipv4_local_port: "); + write_dec(ipv4.local_port as u64); + write_ascii("\r\n"); +} + +fn http_request_with_host( + bs: *mut EfiBootServices, + http: *mut EfiHttpProtocol, + url: &[u8], + label: &str, + host: Option<&[u8]>, +) -> EfiStatus { + let mut url16 = [0u16; URL16_MAX]; + let url16_ptr = match write_utf16_url(url, &mut url16) { + Ok(ptr) => ptr, + Err(status) => return status, + }; + + let mut event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut event, + ) + }; + write_ascii(label); + write_ascii("_request_event_status: "); + write_ascii("0x"); + write_hex64(status.0); + write_ascii("\r\n"); + if status.is_error() { + return status; + } + + let mut request_data = EfiHttpRequestData { + method: HTTP_METHOD_GET, + url: url16_ptr, + }; + let mut host_name = [b'H', b'o', b's', b't', 0]; + let mut host_value = [0u8; 96]; + let mut header = EfiHttpHeader { + field_name: host_name.as_mut_ptr(), + field_value: host_value.as_mut_ptr(), + }; + let mut header_count = 0usize; + let mut headers = null_mut(); + if let Some(host) = host { + if host.len() + 1 <= host_value.len() { + let mut i = 0usize; + while i < host.len() { + host_value[i] = host[i]; + i += 1; + } + host_value[i] = 0; + header_count = 1; + headers = &mut header; + } else { + unsafe { + ((*bs).close_event)(event); + } + return EFI_BUFFER_TOO_SMALL; + } + } + let mut message = EfiHttpMessage { + data: EfiHttpMessageData { + request: &mut request_data, + }, + header_count, + headers, + body_length: 0, + body: null_mut(), + }; + let mut token = EfiHttpToken { + event, + status: EFI_NOT_READY, + message: &mut message, + }; + + let submit_status = unsafe { ((*http).request)(http, &mut token) }; + write_ascii(label); + write_ascii("_request_submit_status: "); + write_ascii("0x"); + write_hex64(submit_status.0); + write_ascii("\r\n"); + let mut final_status = submit_status; + if !submit_status.is_error() { + final_status = poll_http(http, &token); + } else if submit_status == EFI_NOT_FOUND { + write_ascii(label); + write_ascii("_request_not_found_continue_response: yes\r\n"); + unsafe { + ((*http).poll)(http); + } + final_status = EFI_SUCCESS; + } + write_ascii(label); + write_ascii("_request_token_status: "); + write_ascii("0x"); + write_hex64(token.status.0); + write_ascii("\r\n"); + unsafe { + ((*bs).close_event)(event); + } + final_status +} + +fn http_request( + bs: *mut EfiBootServices, + http: *mut EfiHttpProtocol, + url: &[u8], + label: &str, +) -> EfiStatus { + http_request_with_host(bs, http, url, label, None) +} + +fn http_get_once_with_host( + bs: *mut EfiBootServices, + http: *mut EfiHttpProtocol, + url: &[u8], + label: &str, + host: Option<&[u8]>, + body: *mut u8, + body_len: &mut usize, + http_status: &mut u32, +) -> EfiStatus { + let mut url16 = [0u16; URL16_MAX]; + let url16_ptr = match write_utf16_url(url, &mut url16) { + Ok(ptr) => ptr, + Err(status) => return status, + }; + + let mut request_event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut request_event, + ) + }; + write_ascii(label); + write_ascii("_request_event_status: 0x"); + write_hex64(status.0); + write_ascii("\r\n"); + if status.is_error() { + return status; + } + + let mut request_data = EfiHttpRequestData { + method: HTTP_METHOD_GET, + url: url16_ptr, + }; + let mut host_name = [b'H', b'o', b's', b't', 0]; + let mut host_value = [0u8; 96]; + let mut header = EfiHttpHeader { + field_name: host_name.as_mut_ptr(), + field_value: host_value.as_mut_ptr(), + }; + let mut header_count = 0usize; + let mut headers = null_mut(); + if let Some(host) = host { + if host.len() + 1 <= host_value.len() { + let mut i = 0usize; + while i < host.len() { + host_value[i] = host[i]; + i += 1; + } + host_value[i] = 0; + header_count = 1; + headers = &mut header; + } else { + unsafe { + ((*bs).close_event)(request_event); + } + return EFI_BUFFER_TOO_SMALL; + } + } + + let mut request_message = EfiHttpMessage { + data: EfiHttpMessageData { + request: &mut request_data, + }, + header_count, + headers, + body_length: 0, + body: null_mut(), + }; + let mut request_token = EfiHttpToken { + event: request_event, + status: EFI_NOT_READY, + message: &mut request_message, + }; + + let submit_status = unsafe { ((*http).request)(http, &mut request_token) }; + write_ascii(label); + write_ascii("_request_submit_status: 0x"); + write_hex64(submit_status.0); + write_ascii("\r\n"); + let mut request_status = submit_status; + if !submit_status.is_error() { + request_status = poll_http(http, &request_token); + } else if submit_status == EFI_NOT_FOUND { + write_ascii(label); + write_ascii("_request_not_found_keep_context: yes\r\n"); + unsafe { + ((*http).poll)(http); + } + request_status = EFI_SUCCESS; + } + write_ascii(label); + write_ascii("_request_token_status: 0x"); + write_hex64(request_token.status.0); + write_ascii("\r\n"); + write_prefixed_status(label, "_request_completion", request_status); + if request_status.is_error() { + unsafe { + ((*bs).close_event)(request_event); + } + return request_status; + } + + let mut response_event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut response_event, + ) + }; + write_ascii(label); + write_ascii("_response_event_status: 0x"); + write_hex64(status.0); + write_ascii("\r\n"); + if status.is_error() { + unsafe { + ((*bs).close_event)(request_event); + } + return status; + } + + let mut response_data = EfiHttpResponseData { status_code: 0 }; + let mut response_message = EfiHttpMessage { + data: EfiHttpMessageData { + response: &mut response_data, + }, + header_count: 0, + headers: null_mut(), + body_length: *body_len, + body: body as *mut c_void, + }; + let mut response_token = EfiHttpToken { + event: response_event, + status: EFI_NOT_READY, + message: &mut response_message, + }; + + let mut response_status = unsafe { ((*http).response)(http, &mut response_token) }; + write_ascii(label); + write_ascii("_response_submit_status: 0x"); + write_hex64(response_status.0); + write_ascii("\r\n"); + if !response_status.is_error() { + response_status = poll_http(http, &response_token); + } + write_ascii(label); + write_ascii("_response_token_status: 0x"); + write_hex64(response_token.status.0); + write_ascii("\r\n"); + *body_len = response_message.body_length; + *http_status = response_data.status_code; + if !response_message.headers.is_null() { + unsafe { + ((*bs).free_pool)(response_message.headers as *mut c_void); + } + } + unsafe { + ((*bs).close_event)(response_event); + ((*bs).close_event)(request_event); + } + response_status +} + +fn make_https_443_url(input: &[u8], out: &mut [u8]) -> Result { + const PREFIX: &[u8] = b"https://"; + const PORT: &[u8] = b":3443/"; + if input.len() <= PREFIX.len() || !starts_with(input, PREFIX) { + return Err(EFI_UNSUPPORTED); + } + let mut i = PREFIX.len(); + while i + PORT.len() <= input.len() { + if starts_with(&input[i..], PORT) { + let mut n = 0usize; + while n < i { + if n >= out.len() { + return Err(EFI_BUFFER_TOO_SMALL); + } + out[n] = input[n]; + n += 1; + } + let path_start = i + PORT.len() - 1; + let mut j = path_start; + while j < input.len() { + if n >= out.len() { + return Err(EFI_BUFFER_TOO_SMALL); + } + out[n] = input[j]; + n += 1; + j += 1; + } + return Ok(n); + } + i += 1; + } + Err(EFI_UNSUPPORTED) +} + +fn starts_with(haystack: &[u8], needle: &[u8]) -> bool { + if haystack.len() < needle.len() { + return false; + } + let mut i = 0usize; + while i < needle.len() { + if haystack[i] != needle[i] { + return false; + } + i += 1; + } + true +} + +fn http_response( + bs: *mut EfiBootServices, + http: *mut EfiHttpProtocol, + body: *mut u8, + body_len: &mut usize, + http_status: &mut u32, +) -> EfiStatus { + let mut event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut event, + ) + }; + if status.is_error() { + return status; + } + + let mut response_data = EfiHttpResponseData { status_code: 0 }; + let mut message = EfiHttpMessage { + data: EfiHttpMessageData { + response: &mut response_data, + }, + header_count: 0, + headers: null_mut(), + body_length: *body_len, + body: body as *mut c_void, + }; + let mut token = EfiHttpToken { + event, + status: EFI_NOT_READY, + message: &mut message, + }; + + let mut status = unsafe { ((*http).response)(http, &mut token) }; + if !status.is_error() { + status = poll_http(http, &token); + } + *body_len = message.body_length; + *http_status = response_data.status_code; + if !message.headers.is_null() { + unsafe { + ((*bs).free_pool)(message.headers as *mut c_void); + } + } + unsafe { + ((*bs).close_event)(event); + } + status +} + +fn find_key<'a>(json: &'a [u8], key: &[u8]) -> Option<&'a [u8]> { + let mut p = 0; + while p < json.len() { + if json[p] != b'"' { + p += 1; + continue; + } + let mut i = 0; + while i < key.len() && p + 1 + i < json.len() && json[p + 1 + i] == key[i] { + i += 1; + } + if i == key.len() && p + 1 + i < json.len() && json[p + 1 + i] == b'"' { + let mut q = p + 2 + key.len(); + while q < json.len() && matches!(json[q], b' ' | b'\r' | b'\n' | b'\t') { + q += 1; + } + if q < json.len() && json[q] == b':' { + return Some(&json[q + 1..]); + } + } + p += 1; + } + None +} + +fn json_string(json: &[u8], key: &[u8], out: &mut [u8]) -> Result { + let mut p = find_key(json, key).ok_or(())?; + while !p.is_empty() && matches!(p[0], b' ' | b'\r' | b'\n' | b'\t') { + p = &p[1..]; + } + if p.is_empty() || p[0] != b'"' { + return Err(()); + } + p = &p[1..]; + let mut n = 0; + while !p.is_empty() && p[0] != b'"' { + if p[0] == b'\\' || n + 1 >= out.len() { + return Err(()); + } + out[n] = p[0]; + n += 1; + p = &p[1..]; + } + if p.is_empty() || p[0] != b'"' { + return Err(()); + } + if n < out.len() { + out[n] = 0; + } + Ok(n) +} + +fn parse_u64(mut s: &[u8]) -> Result { + let mut value = 0u64; + let mut radix = 10u64; + let mut saw = false; + if s.len() >= 2 && s[0] == b'0' && (s[1] == b'x' || s[1] == b'X') { + radix = 16; + s = &s[2..]; + } + let mut i = 0; + while i < s.len() { + if s[i] == b'_' { + i += 1; + continue; + } + let digit = match s[i] { + b'0'..=b'9' => s[i] - b'0', + b'a'..=b'f' => s[i] - b'a' + 10, + b'A'..=b'F' => s[i] - b'A' + 10, + _ => break, + }; + if digit as u64 >= radix { + return Err(()); + } + value = value * radix + digit as u64; + saw = true; + i += 1; + } + if saw { + Ok(value) + } else { + Err(()) + } +} + +fn json_u64(json: &[u8], key: &[u8]) -> Result { + let mut p = find_key(json, key).ok_or(())?; + while !p.is_empty() && matches!(p[0], b' ' | b'\r' | b'\n' | b'\t') { + p = &p[1..]; + } + parse_u64(p) +} + +fn json_addr_string(json: &[u8], key: &[u8]) -> Result { + let mut buf = [0u8; 64]; + let len = json_string(json, key, &mut buf)?; + parse_u64(&buf[..len]) +} + +fn parse_manifest(json: &[u8]) -> Result { + let mut manifest = Manifest { + kernel_url: [0; 1024], + kernel_url_len: 0, + kernel_size: 0, + kernel_load_addr: 0, + entry_point: 0, + arch: [0; 32], + arch_len: 0, + }; + manifest.kernel_url_len = json_string(json, b"kernel_url", &mut manifest.kernel_url)?; + manifest.kernel_size = json_u64(json, b"kernel_size")?; + manifest.kernel_load_addr = json_addr_string(json, b"kernel_load_addr")?; + manifest.entry_point = json_addr_string(json, b"entry_point")?; + manifest.arch_len = json_string(json, b"arch", &mut manifest.arch)?; + Ok(manifest) +} + +fn page_count(size: u64) -> usize { + ((size as usize) + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE +} + +fn download_kernel( + bs: *mut EfiBootServices, + http: *mut EfiHttpProtocol, + manifest: &Manifest, +) -> EfiStatus { + if manifest.kernel_size == 0 || manifest.kernel_size > MAX_KERNEL_SIZE { + return EFI_UNSUPPORTED; + } + if (manifest.kernel_load_addr as usize % EFI_PAGE_SIZE) != 0 { + return EFI_UNSUPPORTED; + } + + let pages = page_count(manifest.kernel_size); + let mut target = manifest.kernel_load_addr; + let status = unsafe { + ((*bs).allocate_pages)(EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, pages, &mut target) + }; + write_status("kernel_allocate_pages_status: ", status); + write_ascii("kernel_target_addr: 0x"); + write_hex64(target); + write_ascii("\r\n"); + if status.is_error() || target != manifest.kernel_load_addr { + return status; + } + + let status = http_request( + bs, + http, + &manifest.kernel_url[..manifest.kernel_url_len], + "kernel", + ); + write_status("kernel_request_completion: ", status); + if status.is_error() { + unsafe { + ((*bs).free_pages)(target, pages); + } + return status; + } + + let mut downloaded = 0u64; + let mut checksum = 0u32; + while downloaded < manifest.kernel_size { + let remaining = (manifest.kernel_size - downloaded) as usize; + let mut body_len = if remaining < KERNEL_CHUNK { + remaining + } else { + KERNEL_CHUNK + }; + let mut http_status = 0u32; + let dst = (manifest.kernel_load_addr + downloaded) as *mut u8; + let status = http_response(bs, http, dst, &mut body_len, &mut http_status); + if status.is_error() || http_status != HTTP_STATUS_200_OK || body_len == 0 { + write_status("kernel_response_completion: ", status); + write_ascii("kernel_response_status_enum: "); + write_dec(http_status as u64); + write_ascii("\r\n"); + unsafe { + ((*bs).free_pages)(target, pages); + } + return if status.is_error() { + status + } else { + EFI_DEVICE_ERROR + }; + } + let slice = unsafe { core::slice::from_raw_parts(dst, body_len) }; + let mut i = 0; + while i < slice.len() { + checksum = checksum.wrapping_add(slice[i] as u32); + i += 1; + } + downloaded += body_len as u64; + } + + write_ascii("kernel_downloaded_size: "); + write_dec(downloaded); + write_ascii("\r\n"); + write_ascii("kernel_expected_size: "); + write_dec(manifest.kernel_size); + write_ascii("\r\n"); + write_ascii("kernel_checksum32: 0x"); + write_hex64(checksum as u64); + write_ascii("\r\n"); + EFI_SUCCESS +} + +fn print_memory_map(bs: *mut EfiBootServices, map_key_out: &mut usize) -> EfiStatus { + let mut map_size = MEMORY_MAP_MAX; + let mut descriptor_size = 0usize; + let mut descriptor_version = 0u32; + let memory_map = core::ptr::addr_of_mut!(MEMORY_MAP) as *mut EfiMemoryDescriptor; + let status = unsafe { + ((*bs).get_memory_map)( + &mut map_size, + memory_map, + map_key_out, + &mut descriptor_size, + &mut descriptor_version, + ) + }; + write_status("memory_map_status: ", status); + write_ascii("memory_map_size: "); + write_dec(map_size as u64); + write_ascii("\r\n"); + write_ascii("memory_map_key: "); + write_dec(*map_key_out as u64); + write_ascii("\r\n"); + write_ascii("memory_map_descriptor_size: "); + write_dec(descriptor_size as u64); + write_ascii("\r\n"); + status +} + +fn call_kernel(entry_point: u64) -> ! { + let entry: extern "C" fn() = unsafe { core::mem::transmute(entry_point as usize) }; + entry(); + loop { + core::hint::spin_loop(); + } +} + +fn write_prefixed_status(label: &str, suffix: &str, status: EfiStatus) { + write_ascii(label); + write_ascii(suffix); + write_ascii(": 0x"); + write_hex64(status.0); + write_ascii("\r\n"); +} + +fn try_manifest_with_fresh_http_child( + image: EfiHandle, + bs: *mut EfiBootServices, + binding: *mut EfiServiceBindingProtocol, + url: &[u8], + label: &str, + host: Option<&[u8]>, +) -> EfiStatus { + write_ascii(label); + write_ascii("_url: "); + write_bytes(url); + write_ascii("\r\n"); + + let mut child = null_mut(); + let status = unsafe { ((*binding).create_child)(binding, &mut child) }; + write_prefixed_status(label, "_http_create_child_status", status); + if status.is_error() || child.is_null() { + return if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }; + } + + let http = match open_protocol::(bs, child, &EFI_HTTP_PROTOCOL_GUID) { + Ok(http) => { + write_prefixed_status(label, "_http_child_protocol_status", EFI_SUCCESS); + http + } + Err(status) => { + write_prefixed_status(label, "_http_child_protocol_status", status); + unsafe { + ((*binding).destroy_child)(binding, child); + } + return status; + } + }; + + let mut tls_label = [0u8; 96]; + let suffix = b"_http_child_tls_config"; + let mut tls_label_len = 0usize; + while tls_label_len < label.as_bytes().len() && tls_label_len < tls_label.len() { + tls_label[tls_label_len] = label.as_bytes()[tls_label_len]; + tls_label_len += 1; + } + let mut suffix_pos = 0usize; + while suffix_pos < suffix.len() && tls_label_len < tls_label.len() { + tls_label[tls_label_len] = suffix[suffix_pos]; + tls_label_len += 1; + suffix_pos += 1; + } + let tls_label_str = unsafe { core::str::from_utf8_unchecked(&tls_label[..tls_label_len]) }; + configure_tls_ca_on_handle(bs, child, tls_label_str); + + print_http_mode_data(http, "http_pre_configure"); + let status = configure_http(http); + write_prefixed_status(label, "_http_configure_status", status); + if status.is_error() { + unsafe { + ((*binding).destroy_child)(binding, child); + } + return status; + } + print_http_mode_data(http, "http_post_configure"); + warm_up_http(bs, http); + + let mut manifest_body = [0u8; MANIFEST_MAX + 1]; + let mut body_len = MANIFEST_MAX; + let mut http_status = 0u32; + let status = http_get_once_with_host( + bs, + http, + url, + label, + host, + manifest_body.as_mut_ptr(), + &mut body_len, + &mut http_status, + ); + write_status("manifest_response_completion: ", status); + write_ascii("manifest_response_status_enum: "); + write_dec(http_status as u64); + write_ascii("\r\n"); + write_ascii("manifest_response_body_length: "); + write_dec(body_len as u64); + write_ascii("\r\n"); + if status.is_error() || http_status != HTTP_STATUS_200_OK || body_len >= manifest_body.len() { + unsafe { + ((*binding).destroy_child)(binding, child); + } + return if status.is_error() { + status + } else { + EFI_DEVICE_ERROR + }; + } + manifest_body[body_len] = 0; + + let manifest = match parse_manifest(&manifest_body[..body_len]) { + Ok(manifest) => manifest, + Err(_) => { + write_ascii("manifest_parse_failed\r\n"); + unsafe { + ((*binding).destroy_child)(binding, child); + } + return EFI_DEVICE_ERROR; + } + }; + + write_ascii("manifest_arch: "); + write_bytes(&manifest.arch[..manifest.arch_len]); + write_ascii("\r\n"); + write_ascii("manifest_kernel_url: "); + write_bytes(&manifest.kernel_url[..manifest.kernel_url_len]); + write_ascii("\r\n"); + write_ascii("manifest_kernel_size: "); + write_dec(manifest.kernel_size); + write_ascii("\r\n"); + write_ascii("manifest_kernel_load_addr: 0x"); + write_hex64(manifest.kernel_load_addr); + write_ascii("\r\n"); + write_ascii("manifest_entry_point: 0x"); + write_hex64(manifest.entry_point); + write_ascii("\r\n"); + + let status = download_kernel(bs, http, &manifest); + write_status("kernel_download_status: ", status); + if status.is_error() { + unsafe { + ((*binding).destroy_child)(binding, child); + } + return status; + } + + let mut map_key = 0usize; + let status = print_memory_map(bs, &mut map_key); + write_ascii("boot_jump_enabled: "); + write_ascii(if OSTOOL_ENABLE_BOOT_JUMP { + "yes\r\n" + } else { + "no\r\n" + }); + if !OSTOOL_ENABLE_BOOT_JUMP || status.is_error() { + write_ascii("jump_skipped: boot jump disabled\r\n"); + unsafe { + ((*binding).destroy_child)(binding, child); + } + return EFI_SUCCESS; + } + + let status = unsafe { ((*bs).exit_boot_services)(image, map_key) }; + if !status.is_error() { + call_kernel(manifest.entry_point); + } + write_status("exit_boot_services_status: ", status); + write_ascii("jump_failed\r\n"); + unsafe { + ((*binding).destroy_child)(binding, child); + } + EFI_SUCCESS +} + +fn try_http_service_handle( + image: EfiHandle, + bs: *mut EfiBootServices, + service_handle: EfiHandle, + index: usize, +) -> EfiStatus { + write_ascii("http_service_binding_try_index: "); + write_dec(index as u64); + write_ascii("\r\n"); + + let binding = match open_protocol::( + bs, + service_handle, + &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, + ) { + Ok(binding) => { + write_status("http_service_binding_open_status: ", EFI_SUCCESS); + binding + } + Err(status) => { + write_status("http_service_binding_open_status: ", status); + return status; + } + }; + + let status = try_manifest_with_fresh_http_child( + image, + bs, + binding, + OSTOOL_MANIFEST_URL.as_bytes(), + "manifest", + None, + ); + if !status.is_error() { + return status; + } + + let host_3443_status = try_manifest_with_fresh_http_child( + image, + bs, + binding, + OSTOOL_MANIFEST_URL.as_bytes(), + "manifest_host_3443", + Some(b"10.3.10.229:3443"), + ); + if !host_3443_status.is_error() { + return host_3443_status; + } + + let mut url443 = [0u8; URL16_MAX]; + match make_https_443_url(OSTOOL_MANIFEST_URL.as_bytes(), &mut url443) { + Ok(url443_len) => { + let host_443_status = try_manifest_with_fresh_http_child( + image, + bs, + binding, + &url443[..url443_len], + "manifest_host_443", + Some(b"10.3.10.229"), + ); + if !host_443_status.is_error() { + return host_443_status; + } + } + Err(make_status) => { + write_status("manifest_443_url_status: ", make_status); + } + } + + status +} + +#[unsafe(no_mangle)] +#[unsafe(link_section = ".text.efi_main")] +extern "C" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTable) -> EfiStatus { + unsafe { + CONSOLE = if system_table.is_null() { + null_mut() + } else { + (*system_table).con_out + }; + } + write_ascii("ostool LoongArch64 UEFI loader\r\n"); + write_ascii("manifest_url: "); + write_ascii(OSTOOL_MANIFEST_URL); + write_ascii("\r\n"); + + let bs = unsafe { + if system_table.is_null() { + return EFI_SUCCESS; + } + (*system_table).boot_services + }; + if bs.is_null() { + return EFI_SUCCESS; + } + + print_protocol_handle_count( + bs, + "tls_service_binding", + &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, + ); + print_protocol_handle_count( + bs, + "tcp4_service_binding", + &EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID, + ); + configure_tls_ca(bs); + + let mut service_count = 0usize; + let mut service_handles = null_mut(); + let status = locate_protocol_handles( + bs, + &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, + &mut service_count, + &mut service_handles, + ); + write_status("http_service_binding_status: ", status); + write_ascii("http_service_binding_handle_count: "); + write_dec(service_count as u64); + write_ascii("\r\n"); + if status.is_error() || service_count == 0 || service_handles.is_null() { + return EFI_SUCCESS; + } + + let mut i = 0usize; + while i < service_count { + let handle = unsafe { *service_handles.add(i) }; + let status = try_http_service_handle(image, bs, handle, i); + write_status("http_service_binding_try_status: ", status); + if !status.is_error() { + break; + } + i += 1; + } + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } + EFI_SUCCESS +} + +#[panic_handler] +fn panic(_info: &PanicInfo<'_>) -> ! { + loop { + core::hint::spin_loop(); + } +} diff --git a/ostool-server/src/api/router.rs b/ostool-server/src/api/router.rs index b7e85003..54be0975 100644 --- a/ostool-server/src/api/router.rs +++ b/ostool-server/src/api/router.rs @@ -69,6 +69,9 @@ pub fn build_router(state: AppState) -> Router { "/boot/boards/{board_id}/current/{*path}", get(get_http_boot_file), ) + .route("/B.EFI", get(get_http_boot_short_loader)) + .route("/manifest.json", get(get_http_boot_short_manifest)) + .route("/kernel.bin", get(get_http_boot_short_kernel)) .route("/api/v1/admin/overview", get(get_admin_overview)) .route("/api/v1/admin/boards", get(list_boards).post(create_board)) .route("/api/v1/admin/dtbs", get(list_dtbs).post(create_dtb)) @@ -1118,6 +1121,26 @@ async fn get_http_boot_file( State(state): State, ) -> Result { let relative_path = parse_relative_path(&path)?; + read_http_boot_current_file(&state, &board_id, &relative_path).await +} + +async fn get_http_boot_short_loader(State(state): State) -> Result { + read_http_boot_current_file(&state, "l", "BOOTLOONGARCH64.EFI").await +} + +async fn get_http_boot_short_manifest(State(state): State) -> Result { + read_http_boot_current_file(&state, "l", "manifest.json").await +} + +async fn get_http_boot_short_kernel(State(state): State) -> Result { + read_http_boot_current_file(&state, "l", "kernel.bin").await +} + +async fn read_http_boot_current_file( + state: &AppState, + board_id: &str, + relative_path: &str, +) -> Result { let config = state.config.read().await.clone(); if !config.http_boot.enabled { return Err(ApiError::not_found("HTTP Boot is disabled")); diff --git a/scripts/https_static_server.py b/scripts/https_static_server.py new file mode 100644 index 00000000..b95add96 --- /dev/null +++ b/scripts/https_static_server.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +import argparse +import http.server +import ssl +from functools import partial + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--bind", default="0.0.0.0") + parser.add_argument("--port", type=int, default=3443) + parser.add_argument("--root", required=True) + parser.add_argument("--cert", required=True) + parser.add_argument("--key", required=True) + args = parser.parse_args() + + handler = partial(http.server.SimpleHTTPRequestHandler, directory=args.root) + httpd = http.server.ThreadingHTTPServer((args.bind, args.port), handler) + context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + context.load_cert_chain(certfile=args.cert, keyfile=args.key) + httpd.socket = context.wrap_socket(httpd.socket, server_side=True) + print(f"https static server listening on https://{args.bind}:{args.port}/ root={args.root}", flush=True) + httpd.serve_forever() + + +if __name__ == "__main__": + main() From 9b23e5007ae2b54effa692138e9b20f5a45c6b2f Mon Sep 17 00:00:00 2001 From: Josen-B Date: Thu, 14 May 2026 06:25:45 +0000 Subject: [PATCH 23/39] refactor: split monolithic UEFI loader main.rs into modular source files --- loongarch64-uefi-loader/Makefile | 4 +- loongarch64-uefi-loader/src/abi.rs | 431 ++++++ loongarch64-uefi-loader/src/boot.rs | 299 ++++ loongarch64-uefi-loader/src/console.rs | 85 ++ loongarch64-uefi-loader/src/flow.rs | 148 ++ loongarch64-uefi-loader/src/http.rs | 449 ++++++ loongarch64-uefi-loader/src/loader.rs | 15 + loongarch64-uefi-loader/src/main.rs | 1733 +---------------------- loongarch64-uefi-loader/src/manifest.rs | 117 ++ loongarch64-uefi-loader/src/tcp4.rs | 611 ++++++++ loongarch64-uefi-loader/src/tls.rs | 436 ++++++ loongarch64-uefi-loader/src/uefi.rs | 91 ++ 12 files changed, 2687 insertions(+), 1732 deletions(-) create mode 100644 loongarch64-uefi-loader/src/abi.rs create mode 100644 loongarch64-uefi-loader/src/boot.rs create mode 100644 loongarch64-uefi-loader/src/console.rs create mode 100644 loongarch64-uefi-loader/src/flow.rs create mode 100644 loongarch64-uefi-loader/src/http.rs create mode 100644 loongarch64-uefi-loader/src/loader.rs create mode 100644 loongarch64-uefi-loader/src/manifest.rs create mode 100644 loongarch64-uefi-loader/src/tcp4.rs create mode 100644 loongarch64-uefi-loader/src/tls.rs create mode 100644 loongarch64-uefi-loader/src/uefi.rs diff --git a/loongarch64-uefi-loader/Makefile b/loongarch64-uefi-loader/Makefile index 0a0ff118..36aef23f 100644 --- a/loongarch64-uefi-loader/Makefile +++ b/loongarch64-uefi-loader/Makefile @@ -23,7 +23,9 @@ all: $(TARGET) $(OUT_DIR): mkdir -p $@ -$(ELF): src/main.rs loader.lds | $(OUT_DIR) +RUST_SRCS := $(wildcard src/*.rs) + +$(ELF): $(RUST_SRCS) loader.lds | $(OUT_DIR) OSTOOL_MANIFEST_URL="$(MANIFEST_URL)" \ OSTOOL_ENABLE_BOOT_JUMP="$(ENABLE_BOOT_JUMP)" \ $(RUSTC) --edition=2024 \ diff --git a/loongarch64-uefi-loader/src/abi.rs b/loongarch64-uefi-loader/src/abi.rs new file mode 100644 index 00000000..fe1685b2 --- /dev/null +++ b/loongarch64-uefi-loader/src/abi.rs @@ -0,0 +1,431 @@ +type EfiPhysicalAddress = u64; +type EfiVirtualAddress = u64; +type EfiHandle = *mut c_void; +type EfiEvent = *mut c_void; +type EfiTpl = usize; +type EfiMemoryType = u32; +type EfiAllocateType = u32; +type EfiLocateSearchType = u32; + +#[repr(transparent)] +#[derive(Clone, Copy, PartialEq, Eq)] +struct EfiStatus(u64); + +const EFI_SUCCESS: EfiStatus = EfiStatus(0); +const EFI_ERROR_BIT: u64 = 1 << 63; +const EFI_UNSUPPORTED: EfiStatus = EfiStatus(EFI_ERROR_BIT | 3); +const EFI_BUFFER_TOO_SMALL: EfiStatus = EfiStatus(EFI_ERROR_BIT | 5); +const EFI_NOT_READY: EfiStatus = EfiStatus(EFI_ERROR_BIT | 6); +const EFI_DEVICE_ERROR: EfiStatus = EfiStatus(EFI_ERROR_BIT | 7); +const EFI_NOT_FOUND: EfiStatus = EfiStatus(EFI_ERROR_BIT | 14); + +const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 0; +const EFI_LOADER_DATA: EfiMemoryType = 2; +const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; +const EVT_NOTIFY_SIGNAL: u32 = 0x0000_0200; +const TPL_CALLBACK: EfiTpl = 8; +const EFI_PAGE_SIZE: usize = 4096; + +const HTTP_VERSION_11: u32 = 1; +const HTTP_METHOD_GET: u32 = 0; +const HTTP_STATUS_200_OK: u32 = 3; + +const MANIFEST_MAX: usize = 4096; +const URL16_MAX: usize = 1024; +const KERNEL_CHUNK: usize = 16 * 1024; +const MAX_KERNEL_SIZE: u64 = 256 * 1024 * 1024; +const MEMORY_MAP_MAX: usize = 64 * 1024; +const HTTP_POLL_LIMIT: usize = 1_000_000; +const TCP4_POLL_LIMIT: usize = 2_000_000; + +const EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE: u32 = 2; +const EFI_TLS_SESSION_DATA_TYPE_VERSION: u32 = 0; +const EFI_TLS_SESSION_DATA_TYPE_CONNECTION_END: u32 = 1; +const EFI_TLS_SESSION_DATA_TYPE_VERIFY_METHOD: u32 = 5; +const EFI_TLS_CONNECTION_END_CLIENT: u32 = 0; +const EFI_TLS_VERIFY_NONE: u32 = 0; +const VERBOSE_SETUP_LOGS: bool = false; + +#[repr(C)] +#[derive(Clone, Copy)] +struct EfiGuid { + data1: u32, + data2: u16, + data3: u16, + data4: [u8; 8], +} + +#[repr(C)] +struct EfiTableHeader { + signature: u64, + revision: u32, + header_size: u32, + crc32: u32, + reserved: u32, +} + +#[repr(C)] +struct EfiSimpleTextOutputProtocol { + reset: usize, + output_string: extern "C" fn(*mut EfiSimpleTextOutputProtocol, *const u16) -> EfiStatus, +} + +#[repr(C)] +struct EfiMemoryDescriptor { + memory_type: u32, + physical_start: EfiPhysicalAddress, + virtual_start: EfiVirtualAddress, + number_of_pages: u64, + attribute: u64, +} + +#[repr(C)] +struct EfiBootServices { + hdr: EfiTableHeader, + raise_tpl: usize, + restore_tpl: usize, + allocate_pages: + extern "C" fn(EfiAllocateType, EfiMemoryType, usize, *mut EfiPhysicalAddress) -> EfiStatus, + free_pages: extern "C" fn(EfiPhysicalAddress, usize) -> EfiStatus, + get_memory_map: extern "C" fn( + *mut usize, + *mut EfiMemoryDescriptor, + *mut usize, + *mut usize, + *mut u32, + ) -> EfiStatus, + allocate_pool: extern "C" fn(EfiMemoryType, usize, *mut *mut c_void) -> EfiStatus, + free_pool: extern "C" fn(*mut c_void) -> EfiStatus, + create_event: extern "C" fn( + u32, + EfiTpl, + Option, + *mut c_void, + *mut EfiEvent, + ) -> EfiStatus, + set_timer: usize, + wait_for_event: usize, + signal_event: usize, + close_event: extern "C" fn(EfiEvent) -> EfiStatus, + check_event: usize, + install_protocol_interface: usize, + reinstall_protocol_interface: usize, + uninstall_protocol_interface: usize, + handle_protocol: extern "C" fn(EfiHandle, *const EfiGuid, *mut *mut c_void) -> EfiStatus, + reserved: usize, + register_protocol_notify: usize, + locate_handle: usize, + locate_device_path: usize, + install_configuration_table: usize, + load_image: usize, + start_image: usize, + exit: usize, + unload_image: usize, + exit_boot_services: extern "C" fn(EfiHandle, usize) -> EfiStatus, + get_next_monotonic_count: usize, + stall: Option EfiStatus>, + set_watchdog_timer: usize, + connect_controller: usize, + disconnect_controller: usize, + open_protocol: usize, + close_protocol: usize, + open_protocol_information: usize, + protocols_per_handle: usize, + locate_handle_buffer: extern "C" fn( + EfiLocateSearchType, + *const EfiGuid, + *mut c_void, + *mut usize, + *mut *mut EfiHandle, + ) -> EfiStatus, +} + +#[repr(C)] +struct EfiSystemTable { + hdr: EfiTableHeader, + firmware_vendor: *mut u16, + firmware_revision: u32, + console_in_handle: EfiHandle, + con_in: *mut c_void, + console_out_handle: EfiHandle, + con_out: *mut EfiSimpleTextOutputProtocol, + standard_error_handle: EfiHandle, + std_err: *mut EfiSimpleTextOutputProtocol, + runtime_services: *mut c_void, + boot_services: *mut EfiBootServices, +} + +#[repr(C)] +struct EfiServiceBindingProtocol { + create_child: extern "C" fn(*mut EfiServiceBindingProtocol, *mut EfiHandle) -> EfiStatus, + destroy_child: extern "C" fn(*mut EfiServiceBindingProtocol, EfiHandle) -> EfiStatus, +} + +#[repr(C)] +union EfiHttpConfigAccessPoint { + ipv4_node: *mut EfiHttpv4AccessPoint, + ipv6_node: *mut c_void, +} + +#[repr(C)] +struct EfiHttpv4AccessPoint { + use_default_address: u8, + local_address: [u8; 4], + local_subnet: [u8; 4], + local_port: u16, +} + +#[repr(C)] +struct EfiHttpConfigData { + http_version: u32, + timeout_millisec: u32, + local_address_is_ipv6: u8, + padding: [u8; 7], + access_point: EfiHttpConfigAccessPoint, +} + +#[repr(C)] +struct EfiHttpRequestData { + method: u32, + url: *mut u16, +} + +#[repr(C)] +struct EfiHttpResponseData { + status_code: u32, +} + +#[repr(C)] +union EfiHttpMessageData { + request: *mut EfiHttpRequestData, + response: *mut EfiHttpResponseData, +} + +#[repr(C)] +struct EfiHttpHeader { + field_name: *mut u8, + field_value: *mut u8, +} + +#[repr(C)] +struct EfiHttpMessage { + data: EfiHttpMessageData, + header_count: usize, + headers: *mut EfiHttpHeader, + body_length: usize, + body: *mut c_void, +} + +#[repr(C)] +struct EfiHttpToken { + event: EfiEvent, + status: EfiStatus, + message: *mut EfiHttpMessage, +} + +#[repr(C)] +struct EfiHttpProtocol { + get_mode_data: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpConfigData) -> EfiStatus, + configure: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpConfigData) -> EfiStatus, + request: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpToken) -> EfiStatus, + cancel: usize, + response: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpToken) -> EfiStatus, + poll: extern "C" fn(*mut EfiHttpProtocol) -> EfiStatus, +} + +#[repr(C)] +struct EfiTlsConfigurationProtocol { + set_data: extern "C" fn(*mut EfiTlsConfigurationProtocol, u32, *mut c_void, usize) -> EfiStatus, + get_data: + extern "C" fn(*mut EfiTlsConfigurationProtocol, u32, *mut c_void, *mut usize) -> EfiStatus, +} + +#[repr(C)] +#[derive(Clone, Copy)] +struct EfiTlsVersion { + major: u8, + minor: u8, +} + +#[repr(C)] +struct EfiTlsProtocol { + set_session_data: extern "C" fn(*mut EfiTlsProtocol, u32, *mut c_void, usize) -> EfiStatus, + get_session_data: extern "C" fn(*mut EfiTlsProtocol, u32, *mut c_void, *mut usize) -> EfiStatus, + build_response_packet: + extern "C" fn(*mut EfiTlsProtocol, *mut u8, usize, *mut u8, *mut usize) -> EfiStatus, + process_packet: usize, +} + +#[repr(C)] +#[derive(Clone, Copy)] +struct EfiTcp4AccessPoint { + use_default_address: u8, + station_address: [u8; 4], + subnet_mask: [u8; 4], + station_port: u16, + remote_address: [u8; 4], + remote_port: u16, + active_flag: u8, +} + +#[repr(C)] +#[derive(Clone, Copy)] +struct EfiTcp4Option { + receive_buffer_size: u32, + send_buffer_size: u32, + max_syn_back_log: u32, + connection_timeout: u32, + data_retries: u32, + fin_timeout: u32, + time_wait_timeout: u32, + keep_alive_probes: u32, + keep_alive_time: u32, + keep_alive_interval: u32, + enable_nagle: u8, + enable_time_stamp: u8, + enable_window_scaling: u8, + enable_selective_ack: u8, + enable_path_mtu_discovery: u8, +} + +#[repr(C)] +#[derive(Clone, Copy)] +struct EfiTcp4ConfigData { + type_of_service: u8, + time_to_live: u8, + access_point: EfiTcp4AccessPoint, + control_option: EfiTcp4Option, +} + +#[repr(C)] +struct EfiTcp4CompletionToken { + event: EfiEvent, + status: EfiStatus, +} + +#[repr(C)] +struct EfiTcp4ConnectionToken { + completion_token: EfiTcp4CompletionToken, +} + +#[repr(C)] +struct EfiTcp4CloseToken { + completion_token: EfiTcp4CompletionToken, + abort_on_close: u8, +} + +#[repr(C)] +struct EfiTcp4FragmentData { + fragment_length: u32, + fragment_buffer: *mut c_void, +} + +#[repr(C)] +struct EfiTcp4TransmitData { + push: u8, + urgent: u8, + data_length: u32, + fragment_count: u32, + fragment_table: [EfiTcp4FragmentData; 1], +} + +#[repr(C)] +struct EfiTcp4ReceiveData { + urgent_flag: u8, + data_length: u32, + fragment_count: u32, + fragment_table: [EfiTcp4FragmentData; 1], +} + +#[repr(C)] +union EfiTcp4IoPacket { + rx_data: *mut EfiTcp4ReceiveData, + tx_data: *mut EfiTcp4TransmitData, +} + +#[repr(C)] +struct EfiTcp4IoToken { + completion_token: EfiTcp4CompletionToken, + packet: EfiTcp4IoPacket, +} + +#[repr(C)] +struct EfiTcp4Protocol { + get_mode_data: extern "C" fn( + *mut EfiTcp4Protocol, + *mut u32, + *mut EfiTcp4ConfigData, + *mut c_void, + *mut c_void, + *mut c_void, + ) -> EfiStatus, + configure: extern "C" fn(*mut EfiTcp4Protocol, *mut EfiTcp4ConfigData) -> EfiStatus, + routes: usize, + connect: extern "C" fn(*mut EfiTcp4Protocol, *mut EfiTcp4ConnectionToken) -> EfiStatus, + accept: usize, + transmit: extern "C" fn(*mut EfiTcp4Protocol, *mut EfiTcp4IoToken) -> EfiStatus, + receive: extern "C" fn(*mut EfiTcp4Protocol, *mut EfiTcp4IoToken) -> EfiStatus, + close: extern "C" fn(*mut EfiTcp4Protocol, *mut EfiTcp4CloseToken) -> EfiStatus, + cancel: usize, + poll: extern "C" fn(*mut EfiTcp4Protocol) -> EfiStatus, +} + +#[derive(Clone, Copy)] +struct Manifest { + kernel_url: [u8; 1024], + kernel_url_len: usize, + kernel_size: u64, + kernel_load_addr: u64, + entry_point: u64, + arch: [u8; 32], + arch_len: usize, +} + +const EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0xbdc8e6af, + data2: 0xd9bc, + data3: 0x4379, + data4: [0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c], +}; + +const EFI_HTTP_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x7a59b29b, + data2: 0x910b, + data3: 0x4171, + data4: [0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b], +}; + +const EFI_TCP4_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x65530bc7, + data2: 0xa359, + data3: 0x410f, + data4: [0xb0, 0x10, 0x5a, 0xad, 0xc7, 0xec, 0x2b, 0x62], +}; + +const EFI_TLS_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x00ca_959f, + data2: 0x6cfa, + data3: 0x4db1, + data4: [0x95, 0xbc, 0xe4, 0x6c, 0x47, 0x51, 0x43, 0x90], +}; + +const EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x952cb795, + data2: 0xff36, + data3: 0x48cf, + data4: [0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d], +}; + +const EFI_TLS_CONFIGURATION_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x1682fe44, + data2: 0xbd7a, + data3: 0x4407, + data4: [0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d], +}; + +const EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x00720665, + data2: 0x67eb, + data3: 0x4a99, + data4: [0xba, 0xf7, 0xd3, 0xc3, 0x3a, 0x1c, 0x7c, 0xc9], +}; diff --git a/loongarch64-uefi-loader/src/boot.rs b/loongarch64-uefi-loader/src/boot.rs new file mode 100644 index 00000000..05570aa1 --- /dev/null +++ b/loongarch64-uefi-loader/src/boot.rs @@ -0,0 +1,299 @@ +static mut MEMORY_MAP: [u8; MEMORY_MAP_MAX] = [0; MEMORY_MAP_MAX]; + +fn page_count(size: u64) -> usize { + ((size as usize) + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE +} + +fn download_kernel( + bs: *mut EfiBootServices, + http: *mut EfiHttpProtocol, + manifest: &Manifest, +) -> EfiStatus { + if manifest.kernel_size == 0 || manifest.kernel_size > MAX_KERNEL_SIZE { + return EFI_UNSUPPORTED; + } + if (manifest.kernel_load_addr as usize % EFI_PAGE_SIZE) != 0 { + return EFI_UNSUPPORTED; + } + + let pages = page_count(manifest.kernel_size); + let mut target = manifest.kernel_load_addr; + let status = unsafe { + ((*bs).allocate_pages)(EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, pages, &mut target) + }; + write_status("kernel_allocate_pages_status: ", status); + write_ascii("kernel_target_addr: 0x"); + write_hex64(target); + write_ascii("\r\n"); + if status.is_error() || target != manifest.kernel_load_addr { + return status; + } + + let status = http_request( + bs, + http, + &manifest.kernel_url[..manifest.kernel_url_len], + "kernel", + ); + write_status("kernel_request_completion: ", status); + if status.is_error() { + unsafe { + ((*bs).free_pages)(target, pages); + } + return status; + } + + let mut downloaded = 0u64; + let mut checksum = 0u32; + while downloaded < manifest.kernel_size { + let remaining = (manifest.kernel_size - downloaded) as usize; + let mut body_len = if remaining < KERNEL_CHUNK { + remaining + } else { + KERNEL_CHUNK + }; + let mut http_status = 0u32; + let dst = (manifest.kernel_load_addr + downloaded) as *mut u8; + let status = http_response(bs, http, dst, &mut body_len, &mut http_status); + if status.is_error() || http_status != HTTP_STATUS_200_OK || body_len == 0 { + write_status("kernel_response_completion: ", status); + write_ascii("kernel_response_status_enum: "); + write_dec(http_status as u64); + write_ascii("\r\n"); + unsafe { + ((*bs).free_pages)(target, pages); + } + return if status.is_error() { + status + } else { + EFI_DEVICE_ERROR + }; + } + let slice = unsafe { core::slice::from_raw_parts(dst, body_len) }; + let mut i = 0; + while i < slice.len() { + checksum = checksum.wrapping_add(slice[i] as u32); + i += 1; + } + downloaded += body_len as u64; + } + + write_ascii("kernel_downloaded_size: "); + write_dec(downloaded); + write_ascii("\r\n"); + write_ascii("kernel_expected_size: "); + write_dec(manifest.kernel_size); + write_ascii("\r\n"); + write_ascii("kernel_checksum32: 0x"); + write_hex64(checksum as u64); + write_ascii("\r\n"); + EFI_SUCCESS +} + +fn print_memory_map(bs: *mut EfiBootServices, map_key_out: &mut usize) -> EfiStatus { + let mut map_size = MEMORY_MAP_MAX; + let mut descriptor_size = 0usize; + let mut descriptor_version = 0u32; + let memory_map = core::ptr::addr_of_mut!(MEMORY_MAP) as *mut EfiMemoryDescriptor; + let status = unsafe { + ((*bs).get_memory_map)( + &mut map_size, + memory_map, + map_key_out, + &mut descriptor_size, + &mut descriptor_version, + ) + }; + write_status("memory_map_status: ", status); + write_ascii("memory_map_size: "); + write_dec(map_size as u64); + write_ascii("\r\n"); + write_ascii("memory_map_key: "); + write_dec(*map_key_out as u64); + write_ascii("\r\n"); + write_ascii("memory_map_descriptor_size: "); + write_dec(descriptor_size as u64); + write_ascii("\r\n"); + status +} +fn call_kernel(entry_point: u64) -> ! { + let entry: extern "C" fn() = unsafe { core::mem::transmute(entry_point as usize) }; + entry(); + loop { + core::hint::spin_loop(); + } +} + +fn write_prefixed_status(label: &str, suffix: &str, status: EfiStatus) { + write_ascii(label); + write_ascii(suffix); + write_ascii(": 0x"); + write_hex64(status.0); + write_ascii("\r\n"); +} + +fn try_manifest_with_fresh_http_child( + image: EfiHandle, + bs: *mut EfiBootServices, + binding: *mut EfiServiceBindingProtocol, + url: &[u8], + label: &str, + host: Option<&[u8]>, +) -> EfiStatus { + write_ascii(label); + write_ascii("_url: "); + write_bytes(url); + write_ascii("\r\n"); + + let mut child = null_mut(); + let status = unsafe { ((*binding).create_child)(binding, &mut child) }; + if VERBOSE_SETUP_LOGS { + write_prefixed_status(label, "_http_create_child_status", status); + } + if status.is_error() || child.is_null() { + return if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }; + } + + let http = match open_protocol::(bs, child, &EFI_HTTP_PROTOCOL_GUID) { + Ok(http) => { + if VERBOSE_SETUP_LOGS { + write_prefixed_status(label, "_http_child_protocol_status", EFI_SUCCESS); + } + http + } + Err(status) => { + write_prefixed_status(label, "_http_child_protocol_status", status); + unsafe { + ((*binding).destroy_child)(binding, child); + } + return status; + } + }; + + let mut tls_label = [0u8; 96]; + let suffix = b"_http_child_tls_config"; + let mut tls_label_len = 0usize; + while tls_label_len < label.as_bytes().len() && tls_label_len < tls_label.len() { + tls_label[tls_label_len] = label.as_bytes()[tls_label_len]; + tls_label_len += 1; + } + let mut suffix_pos = 0usize; + while suffix_pos < suffix.len() && tls_label_len < tls_label.len() { + tls_label[tls_label_len] = suffix[suffix_pos]; + tls_label_len += 1; + suffix_pos += 1; + } + let tls_label_str = unsafe { core::str::from_utf8_unchecked(&tls_label[..tls_label_len]) }; + configure_tls_ca_on_handle(bs, child, tls_label_str); + + print_http_mode_data(http, "http_pre_configure"); + let status = configure_http(http); + write_prefixed_status(label, "_http_configure_status", status); + if status.is_error() { + unsafe { + ((*binding).destroy_child)(binding, child); + } + return status; + } + print_http_mode_data(http, "http_post_configure"); + warm_up_http(bs, http); + + let mut manifest_body = [0u8; MANIFEST_MAX + 1]; + let mut body_len = MANIFEST_MAX; + let mut http_status = 0u32; + let status = http_get_once_with_host( + bs, + http, + url, + label, + host, + manifest_body.as_mut_ptr(), + &mut body_len, + &mut http_status, + ); + write_status("manifest_response_completion: ", status); + write_ascii("manifest_response_status_enum: "); + write_dec(http_status as u64); + write_ascii("\r\n"); + write_ascii("manifest_response_body_length: "); + write_dec(body_len as u64); + write_ascii("\r\n"); + if status.is_error() || http_status != HTTP_STATUS_200_OK || body_len >= manifest_body.len() { + unsafe { + ((*binding).destroy_child)(binding, child); + } + return if status.is_error() { + status + } else { + EFI_DEVICE_ERROR + }; + } + manifest_body[body_len] = 0; + + let manifest = match parse_manifest(&manifest_body[..body_len]) { + Ok(manifest) => manifest, + Err(_) => { + write_ascii("manifest_parse_failed\r\n"); + unsafe { + ((*binding).destroy_child)(binding, child); + } + return EFI_DEVICE_ERROR; + } + }; + + write_ascii("manifest_arch: "); + write_bytes(&manifest.arch[..manifest.arch_len]); + write_ascii("\r\n"); + write_ascii("manifest_kernel_url: "); + write_bytes(&manifest.kernel_url[..manifest.kernel_url_len]); + write_ascii("\r\n"); + write_ascii("manifest_kernel_size: "); + write_dec(manifest.kernel_size); + write_ascii("\r\n"); + write_ascii("manifest_kernel_load_addr: 0x"); + write_hex64(manifest.kernel_load_addr); + write_ascii("\r\n"); + write_ascii("manifest_entry_point: 0x"); + write_hex64(manifest.entry_point); + write_ascii("\r\n"); + + let status = download_kernel(bs, http, &manifest); + write_status("kernel_download_status: ", status); + if status.is_error() { + unsafe { + ((*binding).destroy_child)(binding, child); + } + return status; + } + + let mut map_key = 0usize; + let status = print_memory_map(bs, &mut map_key); + write_ascii("boot_jump_enabled: "); + write_ascii(if OSTOOL_ENABLE_BOOT_JUMP { + "yes\r\n" + } else { + "no\r\n" + }); + if !OSTOOL_ENABLE_BOOT_JUMP || status.is_error() { + write_ascii("jump_skipped: boot jump disabled\r\n"); + unsafe { + ((*binding).destroy_child)(binding, child); + } + return EFI_SUCCESS; + } + + let status = unsafe { ((*bs).exit_boot_services)(image, map_key) }; + if !status.is_error() { + call_kernel(manifest.entry_point); + } + write_status("exit_boot_services_status: ", status); + write_ascii("jump_failed\r\n"); + unsafe { + ((*binding).destroy_child)(binding, child); + } + EFI_SUCCESS +} diff --git a/loongarch64-uefi-loader/src/console.rs b/loongarch64-uefi-loader/src/console.rs new file mode 100644 index 00000000..08cfd953 --- /dev/null +++ b/loongarch64-uefi-loader/src/console.rs @@ -0,0 +1,85 @@ +static mut CONSOLE: *mut EfiSimpleTextOutputProtocol = null_mut(); +impl EfiStatus { + fn is_error(self) -> bool { + (self.0 & EFI_ERROR_BIT) != 0 + } +} + +fn console() -> *mut EfiSimpleTextOutputProtocol { + unsafe { CONSOLE } +} + +fn write_ascii(s: &str) { + write_bytes(s.as_bytes()); +} + +fn write_bytes(s: &[u8]) { + let out = console(); + if out.is_null() { + return; + } + let mut pos = 0; + while pos < s.len() { + let mut buf = [0u16; 256]; + let mut n = 0; + while pos + n < s.len() && n + 1 < buf.len() { + buf[n] = s[pos + n] as u16; + n += 1; + } + buf[n] = 0; + unsafe { + ((*out).output_string)(out, buf.as_ptr()); + } + pos += n; + } +} + +fn write_hex64(value: u64) { + let mut out = [0u8; 16]; + let mut i = 0; + while i < 16 { + let digit = ((value >> ((15 - i) * 4)) & 0xf) as u8; + out[i] = if digit < 10 { + b'0' + digit + } else { + b'a' + digit - 10 + }; + i += 1; + } + write_bytes(&out); +} + +fn write_dec(mut value: u64) { + let mut out = [0u8; 32]; + let mut pos = out.len(); + if value == 0 { + write_ascii("0"); + return; + } + while value > 0 && pos > 0 { + pos -= 1; + out[pos] = b'0' + (value % 10) as u8; + value /= 10; + } + write_bytes(&out[pos..]); +} + +fn write_status(label: &str, status: EfiStatus) { + write_ascii(label); + write_ascii("0x"); + write_hex64(status.0); + write_ascii("\r\n"); +} + +fn write_utf16_url(url: &[u8], out: &mut [u16]) -> Result<*mut u16, EfiStatus> { + if url.len() + 1 > out.len() { + return Err(EFI_BUFFER_TOO_SMALL); + } + let mut i = 0; + while i < url.len() { + out[i] = url[i] as u16; + i += 1; + } + out[i] = 0; + Ok(out.as_mut_ptr()) +} diff --git a/loongarch64-uefi-loader/src/flow.rs b/loongarch64-uefi-loader/src/flow.rs new file mode 100644 index 00000000..d98de95b --- /dev/null +++ b/loongarch64-uefi-loader/src/flow.rs @@ -0,0 +1,148 @@ +fn try_http_service_handle( + image: EfiHandle, + bs: *mut EfiBootServices, + service_handle: EfiHandle, + index: usize, +) -> EfiStatus { + if VERBOSE_SETUP_LOGS { + write_ascii("http_service_binding_try_index: "); + write_dec(index as u64); + write_ascii("\r\n"); + } + + let binding = match open_protocol::( + bs, + service_handle, + &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, + ) { + Ok(binding) => { + if VERBOSE_SETUP_LOGS { + write_status("http_service_binding_open_status: ", EFI_SUCCESS); + } + binding + } + Err(status) => { + write_status("http_service_binding_open_status: ", status); + return status; + } + }; + + let status = try_manifest_with_fresh_http_child( + image, + bs, + binding, + OSTOOL_MANIFEST_URL.as_bytes(), + "manifest", + None, + ); + if !status.is_error() { + return status; + } + + let host_3443_status = try_manifest_with_fresh_http_child( + image, + bs, + binding, + OSTOOL_MANIFEST_URL.as_bytes(), + "manifest_host_3443", + Some(b"10.3.10.229:3443"), + ); + if !host_3443_status.is_error() { + return host_3443_status; + } + + let mut url443 = [0u8; URL16_MAX]; + match make_https_443_url(OSTOOL_MANIFEST_URL.as_bytes(), &mut url443) { + Ok(url443_len) => { + let host_443_status = try_manifest_with_fresh_http_child( + image, + bs, + binding, + &url443[..url443_len], + "manifest_host_443", + Some(b"10.3.10.229"), + ); + if !host_443_status.is_error() { + return host_443_status; + } + } + Err(make_status) => { + write_status("manifest_443_url_status: ", make_status); + } + } + + status +} + +#[unsafe(no_mangle)] +#[unsafe(link_section = ".text.efi_main")] +extern "C" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTable) -> EfiStatus { + unsafe { + CONSOLE = if system_table.is_null() { + null_mut() + } else { + (*system_table).con_out + }; + } + write_ascii("ostool LoongArch64 UEFI loader\r\n"); + write_ascii("manifest_url: "); + write_ascii(OSTOOL_MANIFEST_URL); + write_ascii("\r\n"); + write_ascii("log_mode: summary\r\n"); + + let bs = unsafe { + if system_table.is_null() { + return EFI_SUCCESS; + } + (*system_table).boot_services + }; + if bs.is_null() { + return EFI_SUCCESS; + } + + print_protocol_handle_count( + bs, + "tls_service_binding", + &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, + ); + print_protocol_handle_count( + bs, + "tcp4_service_binding", + &EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID, + ); + configure_tls_ca(bs); + run_tcp4_probe(bs); + run_tls_clienthello_probe(bs); + tcp4_tls_clienthello_probe(bs); + + let mut service_count = 0usize; + let mut service_handles = null_mut(); + let status = locate_protocol_handles( + bs, + &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, + &mut service_count, + &mut service_handles, + ); + write_status("http_service_binding_status: ", status); + write_ascii("http_service_binding_handle_count: "); + write_dec(service_count as u64); + write_ascii("\r\n"); + if status.is_error() || service_count == 0 || service_handles.is_null() { + return EFI_SUCCESS; + } + + let mut i = 0usize; + while i < service_count { + let handle = unsafe { *service_handles.add(i) }; + let status = try_http_service_handle(image, bs, handle, i); + write_status("http_service_binding_try_status: ", status); + if !status.is_error() { + break; + } + i += 1; + } + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } + EFI_SUCCESS +} diff --git a/loongarch64-uefi-loader/src/http.rs b/loongarch64-uefi-loader/src/http.rs new file mode 100644 index 00000000..d75eeee5 --- /dev/null +++ b/loongarch64-uefi-loader/src/http.rs @@ -0,0 +1,449 @@ +fn configure_http(http: *mut EfiHttpProtocol) -> EfiStatus { + let mut ipv4 = EfiHttpv4AccessPoint { + use_default_address: 1, + local_address: [0; 4], + local_subnet: [0; 4], + local_port: 0, + }; + let mut config = EfiHttpConfigData { + http_version: HTTP_VERSION_11, + timeout_millisec: 0, + local_address_is_ipv6: 0, + padding: [0; 7], + access_point: EfiHttpConfigAccessPoint { + ipv4_node: &mut ipv4, + }, + }; + unsafe { ((*http).configure)(http, &mut config) } +} + +fn print_http_mode_data(http: *mut EfiHttpProtocol, label: &str) { + if !VERBOSE_SETUP_LOGS { + return; + } + let mut ipv4 = EfiHttpv4AccessPoint { + use_default_address: 0, + local_address: [0; 4], + local_subnet: [0; 4], + local_port: 0, + }; + let mut config = EfiHttpConfigData { + http_version: 0, + timeout_millisec: 0, + local_address_is_ipv6: 0, + padding: [0; 7], + access_point: EfiHttpConfigAccessPoint { + ipv4_node: &mut ipv4, + }, + }; + let status = unsafe { ((*http).get_mode_data)(http, &mut config) }; + write_ascii(label); + write_ascii("_get_mode_data_status: 0x"); + write_hex64(status.0); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_mode_http_version: "); + write_dec(config.http_version as u64); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_mode_timeout_ms: "); + write_dec(config.timeout_millisec as u64); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_mode_ipv6: "); + write_dec(config.local_address_is_ipv6 as u64); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_mode_ipv4_default: "); + write_dec(ipv4.use_default_address as u64); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_mode_ipv4_local_port: "); + write_dec(ipv4.local_port as u64); + write_ascii("\r\n"); +} + +fn http_request_with_host( + bs: *mut EfiBootServices, + http: *mut EfiHttpProtocol, + url: &[u8], + label: &str, + host: Option<&[u8]>, +) -> EfiStatus { + let mut url16 = [0u16; URL16_MAX]; + let url16_ptr = match write_utf16_url(url, &mut url16) { + Ok(ptr) => ptr, + Err(status) => return status, + }; + + let mut event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut event, + ) + }; + write_ascii(label); + write_ascii("_request_event_status: "); + write_ascii("0x"); + write_hex64(status.0); + write_ascii("\r\n"); + if status.is_error() { + return status; + } + + let mut request_data = EfiHttpRequestData { + method: HTTP_METHOD_GET, + url: url16_ptr, + }; + let mut host_name = [b'H', b'o', b's', b't', 0]; + let mut host_value = [0u8; 96]; + let mut header = EfiHttpHeader { + field_name: host_name.as_mut_ptr(), + field_value: host_value.as_mut_ptr(), + }; + let mut header_count = 0usize; + let mut headers = null_mut(); + if let Some(host) = host { + if host.len() + 1 <= host_value.len() { + let mut i = 0usize; + while i < host.len() { + host_value[i] = host[i]; + i += 1; + } + host_value[i] = 0; + header_count = 1; + headers = &mut header; + } else { + unsafe { + ((*bs).close_event)(event); + } + return EFI_BUFFER_TOO_SMALL; + } + } + let mut message = EfiHttpMessage { + data: EfiHttpMessageData { + request: &mut request_data, + }, + header_count, + headers, + body_length: 0, + body: null_mut(), + }; + let mut token = EfiHttpToken { + event, + status: EFI_NOT_READY, + message: &mut message, + }; + + let submit_status = unsafe { ((*http).request)(http, &mut token) }; + write_ascii(label); + write_ascii("_request_submit_status: "); + write_ascii("0x"); + write_hex64(submit_status.0); + write_ascii("\r\n"); + let mut final_status = submit_status; + if !submit_status.is_error() { + final_status = poll_http(http, &token); + } else if submit_status == EFI_NOT_FOUND { + write_ascii(label); + write_ascii("_request_not_found_continue_response: yes\r\n"); + unsafe { + ((*http).poll)(http); + } + final_status = EFI_SUCCESS; + } + write_ascii(label); + write_ascii("_request_token_status: "); + write_ascii("0x"); + write_hex64(token.status.0); + write_ascii("\r\n"); + unsafe { + ((*bs).close_event)(event); + } + final_status +} + +fn http_request( + bs: *mut EfiBootServices, + http: *mut EfiHttpProtocol, + url: &[u8], + label: &str, +) -> EfiStatus { + http_request_with_host(bs, http, url, label, None) +} + +fn http_get_once_with_host( + bs: *mut EfiBootServices, + http: *mut EfiHttpProtocol, + url: &[u8], + label: &str, + host: Option<&[u8]>, + body: *mut u8, + body_len: &mut usize, + http_status: &mut u32, +) -> EfiStatus { + let mut url16 = [0u16; URL16_MAX]; + let url16_ptr = match write_utf16_url(url, &mut url16) { + Ok(ptr) => ptr, + Err(status) => return status, + }; + + let mut request_event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut request_event, + ) + }; + write_ascii(label); + write_ascii("_request_event_status: 0x"); + write_hex64(status.0); + write_ascii("\r\n"); + if status.is_error() { + return status; + } + + let mut request_data = EfiHttpRequestData { + method: HTTP_METHOD_GET, + url: url16_ptr, + }; + let mut host_name = [b'H', b'o', b's', b't', 0]; + let mut host_value = [0u8; 96]; + let mut header = EfiHttpHeader { + field_name: host_name.as_mut_ptr(), + field_value: host_value.as_mut_ptr(), + }; + let mut header_count = 0usize; + let mut headers = null_mut(); + if let Some(host) = host { + if host.len() + 1 <= host_value.len() { + let mut i = 0usize; + while i < host.len() { + host_value[i] = host[i]; + i += 1; + } + host_value[i] = 0; + header_count = 1; + headers = &mut header; + } else { + unsafe { + ((*bs).close_event)(request_event); + } + return EFI_BUFFER_TOO_SMALL; + } + } + + let mut request_message = EfiHttpMessage { + data: EfiHttpMessageData { + request: &mut request_data, + }, + header_count, + headers, + body_length: 0, + body: null_mut(), + }; + let mut request_token = EfiHttpToken { + event: request_event, + status: EFI_NOT_READY, + message: &mut request_message, + }; + + let submit_status = unsafe { ((*http).request)(http, &mut request_token) }; + write_ascii(label); + write_ascii("_request_submit_status: 0x"); + write_hex64(submit_status.0); + write_ascii("\r\n"); + let mut request_status = submit_status; + if !submit_status.is_error() { + request_status = poll_http(http, &request_token); + } else if submit_status == EFI_NOT_FOUND { + write_ascii(label); + write_ascii("_request_not_found_keep_context: yes\r\n"); + unsafe { + ((*http).poll)(http); + } + request_status = EFI_SUCCESS; + } + write_ascii(label); + write_ascii("_request_token_status: 0x"); + write_hex64(request_token.status.0); + write_ascii("\r\n"); + write_prefixed_status(label, "_request_completion", request_status); + if request_status.is_error() { + unsafe { + ((*bs).close_event)(request_event); + } + return request_status; + } + + let mut response_event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut response_event, + ) + }; + write_ascii(label); + write_ascii("_response_event_status: 0x"); + write_hex64(status.0); + write_ascii("\r\n"); + if status.is_error() { + unsafe { + ((*bs).close_event)(request_event); + } + return status; + } + + let mut response_data = EfiHttpResponseData { status_code: 0 }; + let mut response_message = EfiHttpMessage { + data: EfiHttpMessageData { + response: &mut response_data, + }, + header_count: 0, + headers: null_mut(), + body_length: *body_len, + body: body as *mut c_void, + }; + let mut response_token = EfiHttpToken { + event: response_event, + status: EFI_NOT_READY, + message: &mut response_message, + }; + + let mut response_status = unsafe { ((*http).response)(http, &mut response_token) }; + write_ascii(label); + write_ascii("_response_submit_status: 0x"); + write_hex64(response_status.0); + write_ascii("\r\n"); + if !response_status.is_error() { + response_status = poll_http(http, &response_token); + } + write_ascii(label); + write_ascii("_response_token_status: 0x"); + write_hex64(response_token.status.0); + write_ascii("\r\n"); + *body_len = response_message.body_length; + *http_status = response_data.status_code; + if !response_message.headers.is_null() { + unsafe { + ((*bs).free_pool)(response_message.headers as *mut c_void); + } + } + unsafe { + ((*bs).close_event)(response_event); + ((*bs).close_event)(request_event); + } + response_status +} + +fn make_https_443_url(input: &[u8], out: &mut [u8]) -> Result { + const PREFIX: &[u8] = b"https://"; + const PORT: &[u8] = b":3443/"; + if input.len() <= PREFIX.len() || !starts_with(input, PREFIX) { + return Err(EFI_UNSUPPORTED); + } + let mut i = PREFIX.len(); + while i + PORT.len() <= input.len() { + if starts_with(&input[i..], PORT) { + let mut n = 0usize; + while n < i { + if n >= out.len() { + return Err(EFI_BUFFER_TOO_SMALL); + } + out[n] = input[n]; + n += 1; + } + let path_start = i + PORT.len() - 1; + let mut j = path_start; + while j < input.len() { + if n >= out.len() { + return Err(EFI_BUFFER_TOO_SMALL); + } + out[n] = input[j]; + n += 1; + j += 1; + } + return Ok(n); + } + i += 1; + } + Err(EFI_UNSUPPORTED) +} + +fn starts_with(haystack: &[u8], needle: &[u8]) -> bool { + if haystack.len() < needle.len() { + return false; + } + let mut i = 0usize; + while i < needle.len() { + if haystack[i] != needle[i] { + return false; + } + i += 1; + } + true +} + +fn http_response( + bs: *mut EfiBootServices, + http: *mut EfiHttpProtocol, + body: *mut u8, + body_len: &mut usize, + http_status: &mut u32, +) -> EfiStatus { + let mut event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut event, + ) + }; + if status.is_error() { + return status; + } + + let mut response_data = EfiHttpResponseData { status_code: 0 }; + let mut message = EfiHttpMessage { + data: EfiHttpMessageData { + response: &mut response_data, + }, + header_count: 0, + headers: null_mut(), + body_length: *body_len, + body: body as *mut c_void, + }; + let mut token = EfiHttpToken { + event, + status: EFI_NOT_READY, + message: &mut message, + }; + + let mut status = unsafe { ((*http).response)(http, &mut token) }; + if !status.is_error() { + status = poll_http(http, &token); + } + *body_len = message.body_length; + *http_status = response_data.status_code; + if !message.headers.is_null() { + unsafe { + ((*bs).free_pool)(message.headers as *mut c_void); + } + } + unsafe { + ((*bs).close_event)(event); + } + status +} diff --git a/loongarch64-uefi-loader/src/loader.rs b/loongarch64-uefi-loader/src/loader.rs new file mode 100644 index 00000000..aa49d033 --- /dev/null +++ b/loongarch64-uefi-loader/src/loader.rs @@ -0,0 +1,15 @@ +use core::ffi::c_void; +use core::ptr::{null_mut, read_volatile}; + +const OSTOOL_MANIFEST_URL: &str = env!("OSTOOL_MANIFEST_URL"); +const OSTOOL_ENABLE_BOOT_JUMP: bool = cfg!(ostool_enable_boot_jump); + +include!("abi.rs"); +include!("console.rs"); +include!("uefi.rs"); +include!("tls.rs"); +include!("tcp4.rs"); +include!("http.rs"); +include!("manifest.rs"); +include!("boot.rs"); +include!("flow.rs"); diff --git a/loongarch64-uefi-loader/src/main.rs b/loongarch64-uefi-loader/src/main.rs index 673959a8..96656a20 100644 --- a/loongarch64-uefi-loader/src/main.rs +++ b/loongarch64-uefi-loader/src/main.rs @@ -1,1738 +1,9 @@ #![no_std] #![no_main] -use core::ffi::c_void; -use core::panic::PanicInfo; -use core::ptr::{null_mut, read_volatile}; - -const OSTOOL_MANIFEST_URL: &str = env!("OSTOOL_MANIFEST_URL"); -const OSTOOL_ENABLE_BOOT_JUMP: bool = cfg!(ostool_enable_boot_jump); - -type EfiPhysicalAddress = u64; -type EfiVirtualAddress = u64; -type EfiHandle = *mut c_void; -type EfiEvent = *mut c_void; -type EfiTpl = usize; -type EfiMemoryType = u32; -type EfiAllocateType = u32; -type EfiLocateSearchType = u32; - -#[repr(transparent)] -#[derive(Clone, Copy, PartialEq, Eq)] -struct EfiStatus(u64); - -const EFI_SUCCESS: EfiStatus = EfiStatus(0); -const EFI_ERROR_BIT: u64 = 1 << 63; -const EFI_UNSUPPORTED: EfiStatus = EfiStatus(EFI_ERROR_BIT | 3); -const EFI_BUFFER_TOO_SMALL: EfiStatus = EfiStatus(EFI_ERROR_BIT | 5); -const EFI_NOT_READY: EfiStatus = EfiStatus(EFI_ERROR_BIT | 6); -const EFI_DEVICE_ERROR: EfiStatus = EfiStatus(EFI_ERROR_BIT | 7); -const EFI_NOT_FOUND: EfiStatus = EfiStatus(EFI_ERROR_BIT | 14); - -const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 0; -const EFI_LOADER_DATA: EfiMemoryType = 2; -const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; -const EVT_NOTIFY_SIGNAL: u32 = 0x0000_0200; -const TPL_CALLBACK: EfiTpl = 8; -const EFI_PAGE_SIZE: usize = 4096; - -const HTTP_VERSION_11: u32 = 1; -const HTTP_METHOD_GET: u32 = 0; -const HTTP_STATUS_200_OK: u32 = 3; - -const MANIFEST_MAX: usize = 4096; -const URL16_MAX: usize = 1024; -const KERNEL_CHUNK: usize = 16 * 1024; -const MAX_KERNEL_SIZE: u64 = 256 * 1024 * 1024; -const MEMORY_MAP_MAX: usize = 64 * 1024; -const HTTP_POLL_LIMIT: usize = 1_000_000; - -const EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE: u32 = 2; - -#[repr(C)] -#[derive(Clone, Copy)] -struct EfiGuid { - data1: u32, - data2: u16, - data3: u16, - data4: [u8; 8], -} - -#[repr(C)] -struct EfiTableHeader { - signature: u64, - revision: u32, - header_size: u32, - crc32: u32, - reserved: u32, -} - -#[repr(C)] -struct EfiSimpleTextOutputProtocol { - reset: usize, - output_string: extern "C" fn(*mut EfiSimpleTextOutputProtocol, *const u16) -> EfiStatus, -} - -#[repr(C)] -struct EfiMemoryDescriptor { - memory_type: u32, - physical_start: EfiPhysicalAddress, - virtual_start: EfiVirtualAddress, - number_of_pages: u64, - attribute: u64, -} - -#[repr(C)] -struct EfiBootServices { - hdr: EfiTableHeader, - raise_tpl: usize, - restore_tpl: usize, - allocate_pages: - extern "C" fn(EfiAllocateType, EfiMemoryType, usize, *mut EfiPhysicalAddress) -> EfiStatus, - free_pages: extern "C" fn(EfiPhysicalAddress, usize) -> EfiStatus, - get_memory_map: extern "C" fn( - *mut usize, - *mut EfiMemoryDescriptor, - *mut usize, - *mut usize, - *mut u32, - ) -> EfiStatus, - allocate_pool: extern "C" fn(EfiMemoryType, usize, *mut *mut c_void) -> EfiStatus, - free_pool: extern "C" fn(*mut c_void) -> EfiStatus, - create_event: extern "C" fn( - u32, - EfiTpl, - Option, - *mut c_void, - *mut EfiEvent, - ) -> EfiStatus, - set_timer: usize, - wait_for_event: usize, - signal_event: usize, - close_event: extern "C" fn(EfiEvent) -> EfiStatus, - check_event: usize, - install_protocol_interface: usize, - reinstall_protocol_interface: usize, - uninstall_protocol_interface: usize, - handle_protocol: extern "C" fn(EfiHandle, *const EfiGuid, *mut *mut c_void) -> EfiStatus, - reserved: usize, - register_protocol_notify: usize, - locate_handle: usize, - locate_device_path: usize, - install_configuration_table: usize, - load_image: usize, - start_image: usize, - exit: usize, - unload_image: usize, - exit_boot_services: extern "C" fn(EfiHandle, usize) -> EfiStatus, - get_next_monotonic_count: usize, - stall: Option EfiStatus>, - set_watchdog_timer: usize, - connect_controller: usize, - disconnect_controller: usize, - open_protocol: usize, - close_protocol: usize, - open_protocol_information: usize, - protocols_per_handle: usize, - locate_handle_buffer: extern "C" fn( - EfiLocateSearchType, - *const EfiGuid, - *mut c_void, - *mut usize, - *mut *mut EfiHandle, - ) -> EfiStatus, -} - -#[repr(C)] -struct EfiSystemTable { - hdr: EfiTableHeader, - firmware_vendor: *mut u16, - firmware_revision: u32, - console_in_handle: EfiHandle, - con_in: *mut c_void, - console_out_handle: EfiHandle, - con_out: *mut EfiSimpleTextOutputProtocol, - standard_error_handle: EfiHandle, - std_err: *mut EfiSimpleTextOutputProtocol, - runtime_services: *mut c_void, - boot_services: *mut EfiBootServices, -} - -#[repr(C)] -struct EfiServiceBindingProtocol { - create_child: extern "C" fn(*mut EfiServiceBindingProtocol, *mut EfiHandle) -> EfiStatus, - destroy_child: extern "C" fn(*mut EfiServiceBindingProtocol, EfiHandle) -> EfiStatus, -} - -#[repr(C)] -union EfiHttpConfigAccessPoint { - ipv4_node: *mut EfiHttpv4AccessPoint, - ipv6_node: *mut c_void, -} - -#[repr(C)] -struct EfiHttpv4AccessPoint { - use_default_address: u8, - local_address: [u8; 4], - local_subnet: [u8; 4], - local_port: u16, -} - -#[repr(C)] -struct EfiHttpConfigData { - http_version: u32, - timeout_millisec: u32, - local_address_is_ipv6: u8, - padding: [u8; 7], - access_point: EfiHttpConfigAccessPoint, -} - -#[repr(C)] -struct EfiHttpRequestData { - method: u32, - url: *mut u16, -} - -#[repr(C)] -struct EfiHttpResponseData { - status_code: u32, -} - -#[repr(C)] -union EfiHttpMessageData { - request: *mut EfiHttpRequestData, - response: *mut EfiHttpResponseData, -} - -#[repr(C)] -struct EfiHttpHeader { - field_name: *mut u8, - field_value: *mut u8, -} - -#[repr(C)] -struct EfiHttpMessage { - data: EfiHttpMessageData, - header_count: usize, - headers: *mut EfiHttpHeader, - body_length: usize, - body: *mut c_void, -} - -#[repr(C)] -struct EfiHttpToken { - event: EfiEvent, - status: EfiStatus, - message: *mut EfiHttpMessage, -} - -#[repr(C)] -struct EfiHttpProtocol { - get_mode_data: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpConfigData) -> EfiStatus, - configure: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpConfigData) -> EfiStatus, - request: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpToken) -> EfiStatus, - cancel: usize, - response: extern "C" fn(*mut EfiHttpProtocol, *mut EfiHttpToken) -> EfiStatus, - poll: extern "C" fn(*mut EfiHttpProtocol) -> EfiStatus, -} - -#[repr(C)] -struct EfiTlsConfigurationProtocol { - set_data: extern "C" fn(*mut EfiTlsConfigurationProtocol, u32, *mut c_void, usize) -> EfiStatus, - get_data: - extern "C" fn(*mut EfiTlsConfigurationProtocol, u32, *mut c_void, *mut usize) -> EfiStatus, -} - -#[derive(Clone, Copy)] -struct Manifest { - kernel_url: [u8; 1024], - kernel_url_len: usize, - kernel_size: u64, - kernel_load_addr: u64, - entry_point: u64, - arch: [u8; 32], - arch_len: usize, -} - -const EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { - data1: 0xbdc8e6af, - data2: 0xd9bc, - data3: 0x4379, - data4: [0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c], -}; - -const EFI_HTTP_PROTOCOL_GUID: EfiGuid = EfiGuid { - data1: 0x7a59b29b, - data2: 0x910b, - data3: 0x4171, - data4: [0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b], -}; - -const EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { - data1: 0x952cb795, - data2: 0xff36, - data3: 0x48cf, - data4: [0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d], -}; - -const EFI_TLS_CONFIGURATION_PROTOCOL_GUID: EfiGuid = EfiGuid { - data1: 0x1682fe44, - data2: 0xbd7a, - data3: 0x4407, - data4: [0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d], -}; - -const EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID: EfiGuid = EfiGuid { - data1: 0x00720665, - data2: 0x67eb, - data3: 0x4a99, - data4: [0xba, 0xf7, 0xd3, 0xc3, 0x3a, 0x1c, 0x7c, 0xc9], -}; - -static HTTPS_CA_PEM: &[u8] = b"-----BEGIN CERTIFICATE-----\n\ -MIIDHjCCAgagAwIBAgIUBJubHQIousJm3ZT9sNPYq0u1AhwwDQYJKoZIhvcNAQEL\n\ -BQAwFjEUMBIGA1UEAwwLMTAuMy4xMC4yMjkwHhcNMjYwNTEzMDkxMTIwWhcNMjYw\n\ -NTIwMDkxMTIwWjAWMRQwEgYDVQQDDAsxMC4zLjEwLjIyOTCCASIwDQYJKoZIhvcN\n\ -AQEBBQADggEPADCCAQoCggEBALb3klUcff8fXYIcsgeQr1gs2rnwbOl/4Unwtulx\n\ -wG1K8joXYwWT4NP4XSOJy8aVuLk0FSd8VB29l6gjduSYzdC1CE9i3bzJnu4E96X/\n\ -EqRWP6QPkQJUizpH3qwxK1sDNJTmoAdq48v3cLgyyDdxzU/iVlWM51izk4njFMzZ\n\ -4PCLFfznANnj8o5diDCQ96uyKxmaXArIeDAAwcTSlJYc7QHWg6WEg+FQcn3TaMKJ\n\ -8rNELrKMrygc71ZdF9r6anud4YMouse6wJmEzGEVSCQ/y3dxd8gr1Ixq3DV9Yj9J\n\ -fZ57GWjWLTi1CWyMAAod8b6xr+o2yHRS2mGIfTEskTHTc+8CAwEAAaNkMGIwHQYD\n\ -VR0OBBYEFIimL7eY9PEocEUee1gz/YxTalmbMB8GA1UdIwQYMBaAFIimL7eY9PEo\n\ -cEUee1gz/YxTalmbMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0RBAgwBocECgMK5TAN\n\ -BgkqhkiG9w0BAQsFAAOCAQEAf1TkdDogQAYDgSUdraZ6WtOrD7MrLH69DZIcMrVf\n\ -GymOgar70uD9s1MEAwAsCgfqN8+kRcR/viWY8e86AzYVralqiLVs9tpR+vrnFejd\n\ -f9KLftc3owFwmiMLR5szwZMENOz2F+TJ8fNZBTXaJuITxrcIwuBym0FqL1pkN4hL\n\ -ikfU5paqfDst5LA/Wu/56XPtP8tFGh498jNsKlAumlQgaX0w+xxGiaGf1WkvTOP8\n\ -bVwyUYVeTIG2utpOKra0gkg42qcPdvRzZsT9REzlp2cxyBx5fkSmS0kXtqg4fT69\n\ -9/dZPxTWismXdZ4HN74kKak5tAB9CwKXvwaLRqOmXEg4hw==\n\ ------END CERTIFICATE-----\n"; - -static mut CONSOLE: *mut EfiSimpleTextOutputProtocol = null_mut(); -static mut MEMORY_MAP: [u8; MEMORY_MAP_MAX] = [0; MEMORY_MAP_MAX]; - -impl EfiStatus { - fn is_error(self) -> bool { - (self.0 & EFI_ERROR_BIT) != 0 - } -} - -fn console() -> *mut EfiSimpleTextOutputProtocol { - unsafe { CONSOLE } -} - -fn write_ascii(s: &str) { - write_bytes(s.as_bytes()); -} - -fn write_bytes(s: &[u8]) { - let out = console(); - if out.is_null() { - return; - } - let mut pos = 0; - while pos < s.len() { - let mut buf = [0u16; 256]; - let mut n = 0; - while pos + n < s.len() && n + 1 < buf.len() { - buf[n] = s[pos + n] as u16; - n += 1; - } - buf[n] = 0; - unsafe { - ((*out).output_string)(out, buf.as_ptr()); - } - pos += n; - } -} +mod loader; -fn write_hex64(value: u64) { - let mut out = [0u8; 16]; - let mut i = 0; - while i < 16 { - let digit = ((value >> ((15 - i) * 4)) & 0xf) as u8; - out[i] = if digit < 10 { - b'0' + digit - } else { - b'a' + digit - 10 - }; - i += 1; - } - write_bytes(&out); -} - -fn write_dec(mut value: u64) { - let mut out = [0u8; 32]; - let mut pos = out.len(); - if value == 0 { - write_ascii("0"); - return; - } - while value > 0 && pos > 0 { - pos -= 1; - out[pos] = b'0' + (value % 10) as u8; - value /= 10; - } - write_bytes(&out[pos..]); -} - -fn write_status(label: &str, status: EfiStatus) { - write_ascii(label); - write_ascii("0x"); - write_hex64(status.0); - write_ascii("\r\n"); -} - -fn write_utf16_url(url: &[u8], out: &mut [u16]) -> Result<*mut u16, EfiStatus> { - if url.len() + 1 > out.len() { - return Err(EFI_BUFFER_TOO_SMALL); - } - let mut i = 0; - while i < url.len() { - out[i] = url[i] as u16; - i += 1; - } - out[i] = 0; - Ok(out.as_mut_ptr()) -} - -extern "C" fn noop_event(_event: EfiEvent, _context: *mut c_void) {} - -fn poll_http(http: *mut EfiHttpProtocol, token: *const EfiHttpToken) -> EfiStatus { - let mut i = 0; - while i < HTTP_POLL_LIMIT { - let status = unsafe { read_volatile(core::ptr::addr_of!((*token).status)) }; - if status != EFI_NOT_READY { - return status; - } - unsafe { - ((*http).poll)(http); - } - i += 1; - } - unsafe { read_volatile(core::ptr::addr_of!((*token).status)) } -} - -fn warm_up_http(bs: *mut EfiBootServices, http: *mut EfiHttpProtocol) { - let mut last_poll = EFI_NOT_READY; - let mut i = 0; - while i < 20 { - unsafe { - if let Some(stall) = (*bs).stall { - stall(100_000); - } - last_poll = ((*http).poll)(http); - } - i += 1; - } - write_status("http_post_configure_poll_status: ", last_poll); -} - -fn locate_protocol_handles( - bs: *mut EfiBootServices, - guid: &EfiGuid, - count: &mut usize, - handles: &mut *mut EfiHandle, -) -> EfiStatus { - *count = 0; - *handles = null_mut(); - unsafe { - ((*bs).locate_handle_buffer)( - EFI_LOCATE_BY_PROTOCOL, - guid as *const EfiGuid, - null_mut(), - count, - handles, - ) - } -} - -fn print_protocol_handle_count(bs: *mut EfiBootServices, label: &str, guid: &EfiGuid) { - let mut count = 0usize; - let mut handles = null_mut(); - let status = locate_protocol_handles(bs, guid, &mut count, &mut handles); - write_ascii(label); - write_ascii("_status: "); - write_ascii("0x"); - write_hex64(status.0); - write_ascii("\r\n"); - write_ascii(label); - write_ascii("_handle_count: "); - write_dec(count as u64); - write_ascii("\r\n"); - if !status.is_error() && !handles.is_null() { - unsafe { - ((*bs).free_pool)(handles as *mut c_void); - } - } -} - -fn open_protocol( - bs: *mut EfiBootServices, - handle: EfiHandle, - guid: &EfiGuid, -) -> Result<*mut T, EfiStatus> { - let mut interface = null_mut(); - let status = unsafe { ((*bs).handle_protocol)(handle, guid as *const EfiGuid, &mut interface) }; - if status.is_error() || interface.is_null() { - return Err(if status.is_error() { - status - } else { - EFI_UNSUPPORTED - }); - } - Ok(interface as *mut T) -} - -fn b64_value(ch: u8) -> Option { - match ch { - b'A'..=b'Z' => Some(ch - b'A'), - b'a'..=b'z' => Some(ch - b'a' + 26), - b'0'..=b'9' => Some(ch - b'0' + 52), - b'+' => Some(62), - b'/' => Some(63), - _ => None, - } -} - -fn pem_to_der(pem: &[u8], out: &mut [u8]) -> Result { - let mut in_body = false; - let mut accum = 0u32; - let mut bits = 0u32; - let mut len = 0usize; - let mut i = 0usize; - while i < pem.len() { - let ch = pem[i]; - if !in_body { - if ch == b'\n' { - in_body = true; - } - i += 1; - continue; - } - if ch == b'-' { - break; - } - if ch == b'=' { - break; - } - if let Some(value) = b64_value(ch) { - accum = (accum << 6) | value as u32; - bits += 6; - while bits >= 8 { - bits -= 8; - if len >= out.len() { - return Err(EFI_BUFFER_TOO_SMALL); - } - out[len] = ((accum >> bits) & 0xff) as u8; - len += 1; - } - } - i += 1; - } - Ok(len) -} - -fn set_tls_ca_variants(tls_config: *mut EfiTlsConfigurationProtocol, label: &str) { - let set_pem_status = unsafe { - ((*tls_config).set_data)( - tls_config, - EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, - HTTPS_CA_PEM.as_ptr() as *mut c_void, - HTTPS_CA_PEM.len(), - ) - }; - if label == "tls_config" { - write_status("tls_config_set_ca_status: ", set_pem_status); - } else { - write_ascii(label); - write_ascii("_set_ca_pem_status: 0x"); - write_hex64(set_pem_status.0); - write_ascii("\r\n"); - } - - let mut der = [0u8; 1536]; - match pem_to_der(HTTPS_CA_PEM, &mut der) { - Ok(der_len) => { - write_ascii(label); - write_ascii("_ca_der_size: "); - write_dec(der_len as u64); - write_ascii("\r\n"); - let set_der_status = unsafe { - ((*tls_config).set_data)( - tls_config, - EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, - der.as_mut_ptr() as *mut c_void, - der_len, - ) - }; - write_ascii(label); - write_ascii("_set_ca_der_status: 0x"); - write_hex64(set_der_status.0); - write_ascii("\r\n"); - } - Err(status) => { - write_ascii(label); - write_ascii("_ca_der_decode_status: 0x"); - write_hex64(status.0); - write_ascii("\r\n"); - } - } -} - -fn configure_tls_ca(bs: *mut EfiBootServices) { - let mut service_count = 0usize; - let mut service_handles = null_mut(); - let status = locate_protocol_handles( - bs, - &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, - &mut service_count, - &mut service_handles, - ); - write_status("tls_config_service_status: ", status); - write_ascii("tls_config_service_handle_count: "); - write_dec(service_count as u64); - write_ascii("\r\n"); - if status.is_error() || service_count == 0 || service_handles.is_null() { - return; - } - - let service_handle = unsafe { *service_handles }; - let binding = match open_protocol::( - bs, - service_handle, - &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, - ) { - Ok(binding) => { - write_status("tls_config_binding_open_status: ", EFI_SUCCESS); - binding - } - Err(status) => { - write_status("tls_config_binding_open_status: ", status); - unsafe { - ((*bs).free_pool)(service_handles as *mut c_void); - } - return; - } - }; - - let mut child = null_mut(); - let status = unsafe { ((*binding).create_child)(binding, &mut child) }; - write_status("tls_config_create_child_status: ", status); - if status.is_error() || child.is_null() { - unsafe { - ((*bs).free_pool)(service_handles as *mut c_void); - } - return; - } - - match open_protocol::( - bs, - child, - &EFI_TLS_CONFIGURATION_PROTOCOL_GUID, - ) { - Ok(tls_config) => { - write_status("tls_config_protocol_status: ", EFI_SUCCESS); - let mut ca_size = 0usize; - let get_status = unsafe { - ((*tls_config).get_data)( - tls_config, - EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, - null_mut(), - &mut ca_size, - ) - }; - write_status("tls_config_get_ca_status: ", get_status); - write_ascii("tls_config_get_ca_size: "); - write_dec(ca_size as u64); - write_ascii("\r\n"); - - set_tls_ca_variants(tls_config, "tls_config"); - - ca_size = 0; - let get_after_status = unsafe { - ((*tls_config).get_data)( - tls_config, - EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, - null_mut(), - &mut ca_size, - ) - }; - write_status("tls_config_get_ca_after_status: ", get_after_status); - write_ascii("tls_config_get_ca_after_size: "); - write_dec(ca_size as u64); - write_ascii("\r\n"); - } - Err(status) => write_status("tls_config_protocol_status: ", status), - } - - let destroy_status = unsafe { ((*binding).destroy_child)(binding, child) }; - write_status("tls_config_destroy_child_status: ", destroy_status); - unsafe { - ((*bs).free_pool)(service_handles as *mut c_void); - } -} - -fn configure_tls_ca_on_handle(bs: *mut EfiBootServices, handle: EfiHandle, label: &str) { - match open_protocol::( - bs, - handle, - &EFI_TLS_CONFIGURATION_PROTOCOL_GUID, - ) { - Ok(tls_config) => { - write_ascii(label); - write_ascii("_protocol_status: 0x"); - write_hex64(EFI_SUCCESS.0); - write_ascii("\r\n"); - - let mut ca_size = 0usize; - let get_status = unsafe { - ((*tls_config).get_data)( - tls_config, - EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, - null_mut(), - &mut ca_size, - ) - }; - write_ascii(label); - write_ascii("_get_ca_status: 0x"); - write_hex64(get_status.0); - write_ascii("\r\n"); - write_ascii(label); - write_ascii("_get_ca_size: "); - write_dec(ca_size as u64); - write_ascii("\r\n"); - - set_tls_ca_variants(tls_config, label); - - ca_size = 0; - let get_after_status = unsafe { - ((*tls_config).get_data)( - tls_config, - EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, - null_mut(), - &mut ca_size, - ) - }; - write_ascii(label); - write_ascii("_get_ca_after_status: 0x"); - write_hex64(get_after_status.0); - write_ascii("\r\n"); - write_ascii(label); - write_ascii("_get_ca_after_size: "); - write_dec(ca_size as u64); - write_ascii("\r\n"); - } - Err(status) => { - write_ascii(label); - write_ascii("_protocol_status: 0x"); - write_hex64(status.0); - write_ascii("\r\n"); - } - } -} - -fn configure_http(http: *mut EfiHttpProtocol) -> EfiStatus { - let mut ipv4 = EfiHttpv4AccessPoint { - use_default_address: 1, - local_address: [0; 4], - local_subnet: [0; 4], - local_port: 0, - }; - let mut config = EfiHttpConfigData { - http_version: HTTP_VERSION_11, - timeout_millisec: 0, - local_address_is_ipv6: 0, - padding: [0; 7], - access_point: EfiHttpConfigAccessPoint { - ipv4_node: &mut ipv4, - }, - }; - unsafe { ((*http).configure)(http, &mut config) } -} - -fn print_http_mode_data(http: *mut EfiHttpProtocol, label: &str) { - let mut ipv4 = EfiHttpv4AccessPoint { - use_default_address: 0, - local_address: [0; 4], - local_subnet: [0; 4], - local_port: 0, - }; - let mut config = EfiHttpConfigData { - http_version: 0, - timeout_millisec: 0, - local_address_is_ipv6: 0, - padding: [0; 7], - access_point: EfiHttpConfigAccessPoint { - ipv4_node: &mut ipv4, - }, - }; - let status = unsafe { ((*http).get_mode_data)(http, &mut config) }; - write_ascii(label); - write_ascii("_get_mode_data_status: 0x"); - write_hex64(status.0); - write_ascii("\r\n"); - write_ascii(label); - write_ascii("_mode_http_version: "); - write_dec(config.http_version as u64); - write_ascii("\r\n"); - write_ascii(label); - write_ascii("_mode_timeout_ms: "); - write_dec(config.timeout_millisec as u64); - write_ascii("\r\n"); - write_ascii(label); - write_ascii("_mode_ipv6: "); - write_dec(config.local_address_is_ipv6 as u64); - write_ascii("\r\n"); - write_ascii(label); - write_ascii("_mode_ipv4_default: "); - write_dec(ipv4.use_default_address as u64); - write_ascii("\r\n"); - write_ascii(label); - write_ascii("_mode_ipv4_local_port: "); - write_dec(ipv4.local_port as u64); - write_ascii("\r\n"); -} - -fn http_request_with_host( - bs: *mut EfiBootServices, - http: *mut EfiHttpProtocol, - url: &[u8], - label: &str, - host: Option<&[u8]>, -) -> EfiStatus { - let mut url16 = [0u16; URL16_MAX]; - let url16_ptr = match write_utf16_url(url, &mut url16) { - Ok(ptr) => ptr, - Err(status) => return status, - }; - - let mut event = null_mut(); - let status = unsafe { - ((*bs).create_event)( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - Some(noop_event), - null_mut(), - &mut event, - ) - }; - write_ascii(label); - write_ascii("_request_event_status: "); - write_ascii("0x"); - write_hex64(status.0); - write_ascii("\r\n"); - if status.is_error() { - return status; - } - - let mut request_data = EfiHttpRequestData { - method: HTTP_METHOD_GET, - url: url16_ptr, - }; - let mut host_name = [b'H', b'o', b's', b't', 0]; - let mut host_value = [0u8; 96]; - let mut header = EfiHttpHeader { - field_name: host_name.as_mut_ptr(), - field_value: host_value.as_mut_ptr(), - }; - let mut header_count = 0usize; - let mut headers = null_mut(); - if let Some(host) = host { - if host.len() + 1 <= host_value.len() { - let mut i = 0usize; - while i < host.len() { - host_value[i] = host[i]; - i += 1; - } - host_value[i] = 0; - header_count = 1; - headers = &mut header; - } else { - unsafe { - ((*bs).close_event)(event); - } - return EFI_BUFFER_TOO_SMALL; - } - } - let mut message = EfiHttpMessage { - data: EfiHttpMessageData { - request: &mut request_data, - }, - header_count, - headers, - body_length: 0, - body: null_mut(), - }; - let mut token = EfiHttpToken { - event, - status: EFI_NOT_READY, - message: &mut message, - }; - - let submit_status = unsafe { ((*http).request)(http, &mut token) }; - write_ascii(label); - write_ascii("_request_submit_status: "); - write_ascii("0x"); - write_hex64(submit_status.0); - write_ascii("\r\n"); - let mut final_status = submit_status; - if !submit_status.is_error() { - final_status = poll_http(http, &token); - } else if submit_status == EFI_NOT_FOUND { - write_ascii(label); - write_ascii("_request_not_found_continue_response: yes\r\n"); - unsafe { - ((*http).poll)(http); - } - final_status = EFI_SUCCESS; - } - write_ascii(label); - write_ascii("_request_token_status: "); - write_ascii("0x"); - write_hex64(token.status.0); - write_ascii("\r\n"); - unsafe { - ((*bs).close_event)(event); - } - final_status -} - -fn http_request( - bs: *mut EfiBootServices, - http: *mut EfiHttpProtocol, - url: &[u8], - label: &str, -) -> EfiStatus { - http_request_with_host(bs, http, url, label, None) -} - -fn http_get_once_with_host( - bs: *mut EfiBootServices, - http: *mut EfiHttpProtocol, - url: &[u8], - label: &str, - host: Option<&[u8]>, - body: *mut u8, - body_len: &mut usize, - http_status: &mut u32, -) -> EfiStatus { - let mut url16 = [0u16; URL16_MAX]; - let url16_ptr = match write_utf16_url(url, &mut url16) { - Ok(ptr) => ptr, - Err(status) => return status, - }; - - let mut request_event = null_mut(); - let status = unsafe { - ((*bs).create_event)( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - Some(noop_event), - null_mut(), - &mut request_event, - ) - }; - write_ascii(label); - write_ascii("_request_event_status: 0x"); - write_hex64(status.0); - write_ascii("\r\n"); - if status.is_error() { - return status; - } - - let mut request_data = EfiHttpRequestData { - method: HTTP_METHOD_GET, - url: url16_ptr, - }; - let mut host_name = [b'H', b'o', b's', b't', 0]; - let mut host_value = [0u8; 96]; - let mut header = EfiHttpHeader { - field_name: host_name.as_mut_ptr(), - field_value: host_value.as_mut_ptr(), - }; - let mut header_count = 0usize; - let mut headers = null_mut(); - if let Some(host) = host { - if host.len() + 1 <= host_value.len() { - let mut i = 0usize; - while i < host.len() { - host_value[i] = host[i]; - i += 1; - } - host_value[i] = 0; - header_count = 1; - headers = &mut header; - } else { - unsafe { - ((*bs).close_event)(request_event); - } - return EFI_BUFFER_TOO_SMALL; - } - } - - let mut request_message = EfiHttpMessage { - data: EfiHttpMessageData { - request: &mut request_data, - }, - header_count, - headers, - body_length: 0, - body: null_mut(), - }; - let mut request_token = EfiHttpToken { - event: request_event, - status: EFI_NOT_READY, - message: &mut request_message, - }; - - let submit_status = unsafe { ((*http).request)(http, &mut request_token) }; - write_ascii(label); - write_ascii("_request_submit_status: 0x"); - write_hex64(submit_status.0); - write_ascii("\r\n"); - let mut request_status = submit_status; - if !submit_status.is_error() { - request_status = poll_http(http, &request_token); - } else if submit_status == EFI_NOT_FOUND { - write_ascii(label); - write_ascii("_request_not_found_keep_context: yes\r\n"); - unsafe { - ((*http).poll)(http); - } - request_status = EFI_SUCCESS; - } - write_ascii(label); - write_ascii("_request_token_status: 0x"); - write_hex64(request_token.status.0); - write_ascii("\r\n"); - write_prefixed_status(label, "_request_completion", request_status); - if request_status.is_error() { - unsafe { - ((*bs).close_event)(request_event); - } - return request_status; - } - - let mut response_event = null_mut(); - let status = unsafe { - ((*bs).create_event)( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - Some(noop_event), - null_mut(), - &mut response_event, - ) - }; - write_ascii(label); - write_ascii("_response_event_status: 0x"); - write_hex64(status.0); - write_ascii("\r\n"); - if status.is_error() { - unsafe { - ((*bs).close_event)(request_event); - } - return status; - } - - let mut response_data = EfiHttpResponseData { status_code: 0 }; - let mut response_message = EfiHttpMessage { - data: EfiHttpMessageData { - response: &mut response_data, - }, - header_count: 0, - headers: null_mut(), - body_length: *body_len, - body: body as *mut c_void, - }; - let mut response_token = EfiHttpToken { - event: response_event, - status: EFI_NOT_READY, - message: &mut response_message, - }; - - let mut response_status = unsafe { ((*http).response)(http, &mut response_token) }; - write_ascii(label); - write_ascii("_response_submit_status: 0x"); - write_hex64(response_status.0); - write_ascii("\r\n"); - if !response_status.is_error() { - response_status = poll_http(http, &response_token); - } - write_ascii(label); - write_ascii("_response_token_status: 0x"); - write_hex64(response_token.status.0); - write_ascii("\r\n"); - *body_len = response_message.body_length; - *http_status = response_data.status_code; - if !response_message.headers.is_null() { - unsafe { - ((*bs).free_pool)(response_message.headers as *mut c_void); - } - } - unsafe { - ((*bs).close_event)(response_event); - ((*bs).close_event)(request_event); - } - response_status -} - -fn make_https_443_url(input: &[u8], out: &mut [u8]) -> Result { - const PREFIX: &[u8] = b"https://"; - const PORT: &[u8] = b":3443/"; - if input.len() <= PREFIX.len() || !starts_with(input, PREFIX) { - return Err(EFI_UNSUPPORTED); - } - let mut i = PREFIX.len(); - while i + PORT.len() <= input.len() { - if starts_with(&input[i..], PORT) { - let mut n = 0usize; - while n < i { - if n >= out.len() { - return Err(EFI_BUFFER_TOO_SMALL); - } - out[n] = input[n]; - n += 1; - } - let path_start = i + PORT.len() - 1; - let mut j = path_start; - while j < input.len() { - if n >= out.len() { - return Err(EFI_BUFFER_TOO_SMALL); - } - out[n] = input[j]; - n += 1; - j += 1; - } - return Ok(n); - } - i += 1; - } - Err(EFI_UNSUPPORTED) -} - -fn starts_with(haystack: &[u8], needle: &[u8]) -> bool { - if haystack.len() < needle.len() { - return false; - } - let mut i = 0usize; - while i < needle.len() { - if haystack[i] != needle[i] { - return false; - } - i += 1; - } - true -} - -fn http_response( - bs: *mut EfiBootServices, - http: *mut EfiHttpProtocol, - body: *mut u8, - body_len: &mut usize, - http_status: &mut u32, -) -> EfiStatus { - let mut event = null_mut(); - let status = unsafe { - ((*bs).create_event)( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - Some(noop_event), - null_mut(), - &mut event, - ) - }; - if status.is_error() { - return status; - } - - let mut response_data = EfiHttpResponseData { status_code: 0 }; - let mut message = EfiHttpMessage { - data: EfiHttpMessageData { - response: &mut response_data, - }, - header_count: 0, - headers: null_mut(), - body_length: *body_len, - body: body as *mut c_void, - }; - let mut token = EfiHttpToken { - event, - status: EFI_NOT_READY, - message: &mut message, - }; - - let mut status = unsafe { ((*http).response)(http, &mut token) }; - if !status.is_error() { - status = poll_http(http, &token); - } - *body_len = message.body_length; - *http_status = response_data.status_code; - if !message.headers.is_null() { - unsafe { - ((*bs).free_pool)(message.headers as *mut c_void); - } - } - unsafe { - ((*bs).close_event)(event); - } - status -} - -fn find_key<'a>(json: &'a [u8], key: &[u8]) -> Option<&'a [u8]> { - let mut p = 0; - while p < json.len() { - if json[p] != b'"' { - p += 1; - continue; - } - let mut i = 0; - while i < key.len() && p + 1 + i < json.len() && json[p + 1 + i] == key[i] { - i += 1; - } - if i == key.len() && p + 1 + i < json.len() && json[p + 1 + i] == b'"' { - let mut q = p + 2 + key.len(); - while q < json.len() && matches!(json[q], b' ' | b'\r' | b'\n' | b'\t') { - q += 1; - } - if q < json.len() && json[q] == b':' { - return Some(&json[q + 1..]); - } - } - p += 1; - } - None -} - -fn json_string(json: &[u8], key: &[u8], out: &mut [u8]) -> Result { - let mut p = find_key(json, key).ok_or(())?; - while !p.is_empty() && matches!(p[0], b' ' | b'\r' | b'\n' | b'\t') { - p = &p[1..]; - } - if p.is_empty() || p[0] != b'"' { - return Err(()); - } - p = &p[1..]; - let mut n = 0; - while !p.is_empty() && p[0] != b'"' { - if p[0] == b'\\' || n + 1 >= out.len() { - return Err(()); - } - out[n] = p[0]; - n += 1; - p = &p[1..]; - } - if p.is_empty() || p[0] != b'"' { - return Err(()); - } - if n < out.len() { - out[n] = 0; - } - Ok(n) -} - -fn parse_u64(mut s: &[u8]) -> Result { - let mut value = 0u64; - let mut radix = 10u64; - let mut saw = false; - if s.len() >= 2 && s[0] == b'0' && (s[1] == b'x' || s[1] == b'X') { - radix = 16; - s = &s[2..]; - } - let mut i = 0; - while i < s.len() { - if s[i] == b'_' { - i += 1; - continue; - } - let digit = match s[i] { - b'0'..=b'9' => s[i] - b'0', - b'a'..=b'f' => s[i] - b'a' + 10, - b'A'..=b'F' => s[i] - b'A' + 10, - _ => break, - }; - if digit as u64 >= radix { - return Err(()); - } - value = value * radix + digit as u64; - saw = true; - i += 1; - } - if saw { - Ok(value) - } else { - Err(()) - } -} - -fn json_u64(json: &[u8], key: &[u8]) -> Result { - let mut p = find_key(json, key).ok_or(())?; - while !p.is_empty() && matches!(p[0], b' ' | b'\r' | b'\n' | b'\t') { - p = &p[1..]; - } - parse_u64(p) -} - -fn json_addr_string(json: &[u8], key: &[u8]) -> Result { - let mut buf = [0u8; 64]; - let len = json_string(json, key, &mut buf)?; - parse_u64(&buf[..len]) -} - -fn parse_manifest(json: &[u8]) -> Result { - let mut manifest = Manifest { - kernel_url: [0; 1024], - kernel_url_len: 0, - kernel_size: 0, - kernel_load_addr: 0, - entry_point: 0, - arch: [0; 32], - arch_len: 0, - }; - manifest.kernel_url_len = json_string(json, b"kernel_url", &mut manifest.kernel_url)?; - manifest.kernel_size = json_u64(json, b"kernel_size")?; - manifest.kernel_load_addr = json_addr_string(json, b"kernel_load_addr")?; - manifest.entry_point = json_addr_string(json, b"entry_point")?; - manifest.arch_len = json_string(json, b"arch", &mut manifest.arch)?; - Ok(manifest) -} - -fn page_count(size: u64) -> usize { - ((size as usize) + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE -} - -fn download_kernel( - bs: *mut EfiBootServices, - http: *mut EfiHttpProtocol, - manifest: &Manifest, -) -> EfiStatus { - if manifest.kernel_size == 0 || manifest.kernel_size > MAX_KERNEL_SIZE { - return EFI_UNSUPPORTED; - } - if (manifest.kernel_load_addr as usize % EFI_PAGE_SIZE) != 0 { - return EFI_UNSUPPORTED; - } - - let pages = page_count(manifest.kernel_size); - let mut target = manifest.kernel_load_addr; - let status = unsafe { - ((*bs).allocate_pages)(EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, pages, &mut target) - }; - write_status("kernel_allocate_pages_status: ", status); - write_ascii("kernel_target_addr: 0x"); - write_hex64(target); - write_ascii("\r\n"); - if status.is_error() || target != manifest.kernel_load_addr { - return status; - } - - let status = http_request( - bs, - http, - &manifest.kernel_url[..manifest.kernel_url_len], - "kernel", - ); - write_status("kernel_request_completion: ", status); - if status.is_error() { - unsafe { - ((*bs).free_pages)(target, pages); - } - return status; - } - - let mut downloaded = 0u64; - let mut checksum = 0u32; - while downloaded < manifest.kernel_size { - let remaining = (manifest.kernel_size - downloaded) as usize; - let mut body_len = if remaining < KERNEL_CHUNK { - remaining - } else { - KERNEL_CHUNK - }; - let mut http_status = 0u32; - let dst = (manifest.kernel_load_addr + downloaded) as *mut u8; - let status = http_response(bs, http, dst, &mut body_len, &mut http_status); - if status.is_error() || http_status != HTTP_STATUS_200_OK || body_len == 0 { - write_status("kernel_response_completion: ", status); - write_ascii("kernel_response_status_enum: "); - write_dec(http_status as u64); - write_ascii("\r\n"); - unsafe { - ((*bs).free_pages)(target, pages); - } - return if status.is_error() { - status - } else { - EFI_DEVICE_ERROR - }; - } - let slice = unsafe { core::slice::from_raw_parts(dst, body_len) }; - let mut i = 0; - while i < slice.len() { - checksum = checksum.wrapping_add(slice[i] as u32); - i += 1; - } - downloaded += body_len as u64; - } - - write_ascii("kernel_downloaded_size: "); - write_dec(downloaded); - write_ascii("\r\n"); - write_ascii("kernel_expected_size: "); - write_dec(manifest.kernel_size); - write_ascii("\r\n"); - write_ascii("kernel_checksum32: 0x"); - write_hex64(checksum as u64); - write_ascii("\r\n"); - EFI_SUCCESS -} - -fn print_memory_map(bs: *mut EfiBootServices, map_key_out: &mut usize) -> EfiStatus { - let mut map_size = MEMORY_MAP_MAX; - let mut descriptor_size = 0usize; - let mut descriptor_version = 0u32; - let memory_map = core::ptr::addr_of_mut!(MEMORY_MAP) as *mut EfiMemoryDescriptor; - let status = unsafe { - ((*bs).get_memory_map)( - &mut map_size, - memory_map, - map_key_out, - &mut descriptor_size, - &mut descriptor_version, - ) - }; - write_status("memory_map_status: ", status); - write_ascii("memory_map_size: "); - write_dec(map_size as u64); - write_ascii("\r\n"); - write_ascii("memory_map_key: "); - write_dec(*map_key_out as u64); - write_ascii("\r\n"); - write_ascii("memory_map_descriptor_size: "); - write_dec(descriptor_size as u64); - write_ascii("\r\n"); - status -} - -fn call_kernel(entry_point: u64) -> ! { - let entry: extern "C" fn() = unsafe { core::mem::transmute(entry_point as usize) }; - entry(); - loop { - core::hint::spin_loop(); - } -} - -fn write_prefixed_status(label: &str, suffix: &str, status: EfiStatus) { - write_ascii(label); - write_ascii(suffix); - write_ascii(": 0x"); - write_hex64(status.0); - write_ascii("\r\n"); -} - -fn try_manifest_with_fresh_http_child( - image: EfiHandle, - bs: *mut EfiBootServices, - binding: *mut EfiServiceBindingProtocol, - url: &[u8], - label: &str, - host: Option<&[u8]>, -) -> EfiStatus { - write_ascii(label); - write_ascii("_url: "); - write_bytes(url); - write_ascii("\r\n"); - - let mut child = null_mut(); - let status = unsafe { ((*binding).create_child)(binding, &mut child) }; - write_prefixed_status(label, "_http_create_child_status", status); - if status.is_error() || child.is_null() { - return if status.is_error() { - status - } else { - EFI_UNSUPPORTED - }; - } - - let http = match open_protocol::(bs, child, &EFI_HTTP_PROTOCOL_GUID) { - Ok(http) => { - write_prefixed_status(label, "_http_child_protocol_status", EFI_SUCCESS); - http - } - Err(status) => { - write_prefixed_status(label, "_http_child_protocol_status", status); - unsafe { - ((*binding).destroy_child)(binding, child); - } - return status; - } - }; - - let mut tls_label = [0u8; 96]; - let suffix = b"_http_child_tls_config"; - let mut tls_label_len = 0usize; - while tls_label_len < label.as_bytes().len() && tls_label_len < tls_label.len() { - tls_label[tls_label_len] = label.as_bytes()[tls_label_len]; - tls_label_len += 1; - } - let mut suffix_pos = 0usize; - while suffix_pos < suffix.len() && tls_label_len < tls_label.len() { - tls_label[tls_label_len] = suffix[suffix_pos]; - tls_label_len += 1; - suffix_pos += 1; - } - let tls_label_str = unsafe { core::str::from_utf8_unchecked(&tls_label[..tls_label_len]) }; - configure_tls_ca_on_handle(bs, child, tls_label_str); - - print_http_mode_data(http, "http_pre_configure"); - let status = configure_http(http); - write_prefixed_status(label, "_http_configure_status", status); - if status.is_error() { - unsafe { - ((*binding).destroy_child)(binding, child); - } - return status; - } - print_http_mode_data(http, "http_post_configure"); - warm_up_http(bs, http); - - let mut manifest_body = [0u8; MANIFEST_MAX + 1]; - let mut body_len = MANIFEST_MAX; - let mut http_status = 0u32; - let status = http_get_once_with_host( - bs, - http, - url, - label, - host, - manifest_body.as_mut_ptr(), - &mut body_len, - &mut http_status, - ); - write_status("manifest_response_completion: ", status); - write_ascii("manifest_response_status_enum: "); - write_dec(http_status as u64); - write_ascii("\r\n"); - write_ascii("manifest_response_body_length: "); - write_dec(body_len as u64); - write_ascii("\r\n"); - if status.is_error() || http_status != HTTP_STATUS_200_OK || body_len >= manifest_body.len() { - unsafe { - ((*binding).destroy_child)(binding, child); - } - return if status.is_error() { - status - } else { - EFI_DEVICE_ERROR - }; - } - manifest_body[body_len] = 0; - - let manifest = match parse_manifest(&manifest_body[..body_len]) { - Ok(manifest) => manifest, - Err(_) => { - write_ascii("manifest_parse_failed\r\n"); - unsafe { - ((*binding).destroy_child)(binding, child); - } - return EFI_DEVICE_ERROR; - } - }; - - write_ascii("manifest_arch: "); - write_bytes(&manifest.arch[..manifest.arch_len]); - write_ascii("\r\n"); - write_ascii("manifest_kernel_url: "); - write_bytes(&manifest.kernel_url[..manifest.kernel_url_len]); - write_ascii("\r\n"); - write_ascii("manifest_kernel_size: "); - write_dec(manifest.kernel_size); - write_ascii("\r\n"); - write_ascii("manifest_kernel_load_addr: 0x"); - write_hex64(manifest.kernel_load_addr); - write_ascii("\r\n"); - write_ascii("manifest_entry_point: 0x"); - write_hex64(manifest.entry_point); - write_ascii("\r\n"); - - let status = download_kernel(bs, http, &manifest); - write_status("kernel_download_status: ", status); - if status.is_error() { - unsafe { - ((*binding).destroy_child)(binding, child); - } - return status; - } - - let mut map_key = 0usize; - let status = print_memory_map(bs, &mut map_key); - write_ascii("boot_jump_enabled: "); - write_ascii(if OSTOOL_ENABLE_BOOT_JUMP { - "yes\r\n" - } else { - "no\r\n" - }); - if !OSTOOL_ENABLE_BOOT_JUMP || status.is_error() { - write_ascii("jump_skipped: boot jump disabled\r\n"); - unsafe { - ((*binding).destroy_child)(binding, child); - } - return EFI_SUCCESS; - } - - let status = unsafe { ((*bs).exit_boot_services)(image, map_key) }; - if !status.is_error() { - call_kernel(manifest.entry_point); - } - write_status("exit_boot_services_status: ", status); - write_ascii("jump_failed\r\n"); - unsafe { - ((*binding).destroy_child)(binding, child); - } - EFI_SUCCESS -} - -fn try_http_service_handle( - image: EfiHandle, - bs: *mut EfiBootServices, - service_handle: EfiHandle, - index: usize, -) -> EfiStatus { - write_ascii("http_service_binding_try_index: "); - write_dec(index as u64); - write_ascii("\r\n"); - - let binding = match open_protocol::( - bs, - service_handle, - &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, - ) { - Ok(binding) => { - write_status("http_service_binding_open_status: ", EFI_SUCCESS); - binding - } - Err(status) => { - write_status("http_service_binding_open_status: ", status); - return status; - } - }; - - let status = try_manifest_with_fresh_http_child( - image, - bs, - binding, - OSTOOL_MANIFEST_URL.as_bytes(), - "manifest", - None, - ); - if !status.is_error() { - return status; - } - - let host_3443_status = try_manifest_with_fresh_http_child( - image, - bs, - binding, - OSTOOL_MANIFEST_URL.as_bytes(), - "manifest_host_3443", - Some(b"10.3.10.229:3443"), - ); - if !host_3443_status.is_error() { - return host_3443_status; - } - - let mut url443 = [0u8; URL16_MAX]; - match make_https_443_url(OSTOOL_MANIFEST_URL.as_bytes(), &mut url443) { - Ok(url443_len) => { - let host_443_status = try_manifest_with_fresh_http_child( - image, - bs, - binding, - &url443[..url443_len], - "manifest_host_443", - Some(b"10.3.10.229"), - ); - if !host_443_status.is_error() { - return host_443_status; - } - } - Err(make_status) => { - write_status("manifest_443_url_status: ", make_status); - } - } - - status -} - -#[unsafe(no_mangle)] -#[unsafe(link_section = ".text.efi_main")] -extern "C" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTable) -> EfiStatus { - unsafe { - CONSOLE = if system_table.is_null() { - null_mut() - } else { - (*system_table).con_out - }; - } - write_ascii("ostool LoongArch64 UEFI loader\r\n"); - write_ascii("manifest_url: "); - write_ascii(OSTOOL_MANIFEST_URL); - write_ascii("\r\n"); - - let bs = unsafe { - if system_table.is_null() { - return EFI_SUCCESS; - } - (*system_table).boot_services - }; - if bs.is_null() { - return EFI_SUCCESS; - } - - print_protocol_handle_count( - bs, - "tls_service_binding", - &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, - ); - print_protocol_handle_count( - bs, - "tcp4_service_binding", - &EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID, - ); - configure_tls_ca(bs); - - let mut service_count = 0usize; - let mut service_handles = null_mut(); - let status = locate_protocol_handles( - bs, - &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, - &mut service_count, - &mut service_handles, - ); - write_status("http_service_binding_status: ", status); - write_ascii("http_service_binding_handle_count: "); - write_dec(service_count as u64); - write_ascii("\r\n"); - if status.is_error() || service_count == 0 || service_handles.is_null() { - return EFI_SUCCESS; - } - - let mut i = 0usize; - while i < service_count { - let handle = unsafe { *service_handles.add(i) }; - let status = try_http_service_handle(image, bs, handle, i); - write_status("http_service_binding_try_status: ", status); - if !status.is_error() { - break; - } - i += 1; - } - unsafe { - ((*bs).free_pool)(service_handles as *mut c_void); - } - EFI_SUCCESS -} +use core::panic::PanicInfo; #[panic_handler] fn panic(_info: &PanicInfo<'_>) -> ! { diff --git a/loongarch64-uefi-loader/src/manifest.rs b/loongarch64-uefi-loader/src/manifest.rs new file mode 100644 index 00000000..6bcb5803 --- /dev/null +++ b/loongarch64-uefi-loader/src/manifest.rs @@ -0,0 +1,117 @@ +fn find_key<'a>(json: &'a [u8], key: &[u8]) -> Option<&'a [u8]> { + let mut p = 0; + while p < json.len() { + if json[p] != b'"' { + p += 1; + continue; + } + let mut i = 0; + while i < key.len() && p + 1 + i < json.len() && json[p + 1 + i] == key[i] { + i += 1; + } + if i == key.len() && p + 1 + i < json.len() && json[p + 1 + i] == b'"' { + let mut q = p + 2 + key.len(); + while q < json.len() && matches!(json[q], b' ' | b'\r' | b'\n' | b'\t') { + q += 1; + } + if q < json.len() && json[q] == b':' { + return Some(&json[q + 1..]); + } + } + p += 1; + } + None +} + +fn json_string(json: &[u8], key: &[u8], out: &mut [u8]) -> Result { + let mut p = find_key(json, key).ok_or(())?; + while !p.is_empty() && matches!(p[0], b' ' | b'\r' | b'\n' | b'\t') { + p = &p[1..]; + } + if p.is_empty() || p[0] != b'"' { + return Err(()); + } + p = &p[1..]; + let mut n = 0; + while !p.is_empty() && p[0] != b'"' { + if p[0] == b'\\' || n + 1 >= out.len() { + return Err(()); + } + out[n] = p[0]; + n += 1; + p = &p[1..]; + } + if p.is_empty() || p[0] != b'"' { + return Err(()); + } + if n < out.len() { + out[n] = 0; + } + Ok(n) +} + +fn parse_u64(mut s: &[u8]) -> Result { + let mut value = 0u64; + let mut radix = 10u64; + let mut saw = false; + if s.len() >= 2 && s[0] == b'0' && (s[1] == b'x' || s[1] == b'X') { + radix = 16; + s = &s[2..]; + } + let mut i = 0; + while i < s.len() { + if s[i] == b'_' { + i += 1; + continue; + } + let digit = match s[i] { + b'0'..=b'9' => s[i] - b'0', + b'a'..=b'f' => s[i] - b'a' + 10, + b'A'..=b'F' => s[i] - b'A' + 10, + _ => break, + }; + if digit as u64 >= radix { + return Err(()); + } + value = value * radix + digit as u64; + saw = true; + i += 1; + } + if saw { + Ok(value) + } else { + Err(()) + } +} + +fn json_u64(json: &[u8], key: &[u8]) -> Result { + let mut p = find_key(json, key).ok_or(())?; + while !p.is_empty() && matches!(p[0], b' ' | b'\r' | b'\n' | b'\t') { + p = &p[1..]; + } + parse_u64(p) +} + +fn json_addr_string(json: &[u8], key: &[u8]) -> Result { + let mut buf = [0u8; 64]; + let len = json_string(json, key, &mut buf)?; + parse_u64(&buf[..len]) +} + +fn parse_manifest(json: &[u8]) -> Result { + let mut manifest = Manifest { + kernel_url: [0; 1024], + kernel_url_len: 0, + kernel_size: 0, + kernel_load_addr: 0, + entry_point: 0, + arch: [0; 32], + arch_len: 0, + }; + manifest.kernel_url_len = json_string(json, b"kernel_url", &mut manifest.kernel_url)?; + manifest.kernel_size = json_u64(json, b"kernel_size")?; + manifest.kernel_load_addr = json_addr_string(json, b"kernel_load_addr")?; + manifest.entry_point = json_addr_string(json, b"entry_point")?; + manifest.arch_len = json_string(json, b"arch", &mut manifest.arch)?; + Ok(manifest) +} diff --git a/loongarch64-uefi-loader/src/tcp4.rs b/loongarch64-uefi-loader/src/tcp4.rs new file mode 100644 index 00000000..000ac53e --- /dev/null +++ b/loongarch64-uefi-loader/src/tcp4.rs @@ -0,0 +1,611 @@ +fn poll_tcp4(tcp4: *mut EfiTcp4Protocol, token: *const EfiTcp4CompletionToken) -> EfiStatus { + let mut i = 0usize; + while i < TCP4_POLL_LIMIT { + let status = unsafe { read_volatile(core::ptr::addr_of!((*token).status)) }; + if status != EFI_NOT_READY { + return status; + } + unsafe { + ((*tcp4).poll)(tcp4); + } + i += 1; + } + unsafe { read_volatile(core::ptr::addr_of!((*token).status)) } +} + +fn tcp4_connect_probe( + bs: *mut EfiBootServices, + binding: *mut EfiServiceBindingProtocol, + remote: [u8; 4], + port: u16, + label: &str, +) -> EfiStatus { + let mut child = null_mut(); + let status = unsafe { ((*binding).create_child)(binding, &mut child) }; + write_prefixed_status(label, "_create_child_status", status); + if status.is_error() || child.is_null() { + return if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }; + } + + let tcp4 = match open_protocol::(bs, child, &EFI_TCP4_PROTOCOL_GUID) { + Ok(tcp4) => { + write_prefixed_status(label, "_protocol_status", EFI_SUCCESS); + tcp4 + } + Err(status) => { + write_prefixed_status(label, "_protocol_status", status); + unsafe { + ((*binding).destroy_child)(binding, child); + } + return status; + } + }; + + let mut config = EfiTcp4ConfigData { + type_of_service: 0, + time_to_live: 64, + access_point: EfiTcp4AccessPoint { + use_default_address: 1, + station_address: [0; 4], + subnet_mask: [0; 4], + station_port: 0, + remote_address: remote, + remote_port: port, + active_flag: 1, + }, + control_option: EfiTcp4Option { + receive_buffer_size: 0, + send_buffer_size: 0, + max_syn_back_log: 0, + connection_timeout: 0, + data_retries: 0, + fin_timeout: 0, + time_wait_timeout: 0, + keep_alive_probes: 0, + keep_alive_time: 0, + keep_alive_interval: 0, + enable_nagle: 0, + enable_time_stamp: 0, + enable_window_scaling: 0, + enable_selective_ack: 0, + enable_path_mtu_discovery: 0, + }, + }; + + let status = unsafe { ((*tcp4).configure)(tcp4, &mut config) }; + write_prefixed_status(label, "_configure_status", status); + if status.is_error() { + unsafe { + ((*binding).destroy_child)(binding, child); + } + return status; + } + + let mut event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut event, + ) + }; + write_prefixed_status(label, "_connect_event_status", status); + if status.is_error() { + unsafe { + ((*tcp4).configure)(tcp4, null_mut()); + ((*binding).destroy_child)(binding, child); + } + return status; + } + + let mut token = EfiTcp4ConnectionToken { + completion_token: EfiTcp4CompletionToken { + event, + status: EFI_NOT_READY, + }, + }; + let submit_status = unsafe { ((*tcp4).connect)(tcp4, &mut token) }; + write_prefixed_status(label, "_connect_submit_status", submit_status); + + let completion = if submit_status.is_error() { + submit_status + } else { + poll_tcp4(tcp4, &token.completion_token) + }; + write_prefixed_status(label, "_connect_completion", completion); + write_prefixed_status( + label, + "_connect_token_status", + token.completion_token.status, + ); + + let mut close_event = null_mut(); + let close_event_status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut close_event, + ) + }; + write_prefixed_status(label, "_close_event_status", close_event_status); + if !close_event_status.is_error() { + let mut close_token = EfiTcp4CloseToken { + completion_token: EfiTcp4CompletionToken { + event: close_event, + status: EFI_NOT_READY, + }, + abort_on_close: 1, + }; + let close_submit_status = unsafe { ((*tcp4).close)(tcp4, &mut close_token) }; + write_prefixed_status(label, "_close_submit_status", close_submit_status); + if !close_submit_status.is_error() { + let close_completion = poll_tcp4(tcp4, &close_token.completion_token); + write_prefixed_status(label, "_close_completion", close_completion); + } + unsafe { + ((*bs).close_event)(close_event); + } + } + + unsafe { + ((*bs).close_event)(event); + ((*tcp4).configure)(tcp4, null_mut()); + ((*binding).destroy_child)(binding, child); + } + + completion +} + +fn tcp4_transmit_once( + bs: *mut EfiBootServices, + tcp4: *mut EfiTcp4Protocol, + bytes: &mut [u8], + label: &str, +) -> EfiStatus { + let mut event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut event, + ) + }; + write_prefixed_status(label, "_tx_event_status", status); + if status.is_error() { + return status; + } + + let mut tx_data = EfiTcp4TransmitData { + push: 1, + urgent: 0, + data_length: bytes.len() as u32, + fragment_count: 1, + fragment_table: [EfiTcp4FragmentData { + fragment_length: bytes.len() as u32, + fragment_buffer: bytes.as_mut_ptr() as *mut c_void, + }], + }; + let mut token = EfiTcp4IoToken { + completion_token: EfiTcp4CompletionToken { + event, + status: EFI_NOT_READY, + }, + packet: EfiTcp4IoPacket { + tx_data: &mut tx_data, + }, + }; + + let submit_status = unsafe { ((*tcp4).transmit)(tcp4, &mut token) }; + write_prefixed_status(label, "_tx_submit_status", submit_status); + let completion = if submit_status.is_error() { + submit_status + } else { + poll_tcp4(tcp4, &token.completion_token) + }; + write_prefixed_status(label, "_tx_completion", completion); + write_prefixed_status(label, "_tx_token_status", token.completion_token.status); + unsafe { + ((*bs).close_event)(event); + } + completion +} + +fn tcp4_receive_once( + bs: *mut EfiBootServices, + tcp4: *mut EfiTcp4Protocol, + out: &mut [u8], + received_len: &mut usize, + label: &str, +) -> EfiStatus { + *received_len = 0; + let mut event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut event, + ) + }; + write_prefixed_status(label, "_rx_event_status", status); + if status.is_error() { + return status; + } + + let mut rx_data = EfiTcp4ReceiveData { + urgent_flag: 0, + data_length: out.len() as u32, + fragment_count: 1, + fragment_table: [EfiTcp4FragmentData { + fragment_length: out.len() as u32, + fragment_buffer: out.as_mut_ptr() as *mut c_void, + }], + }; + let mut token = EfiTcp4IoToken { + completion_token: EfiTcp4CompletionToken { + event, + status: EFI_NOT_READY, + }, + packet: EfiTcp4IoPacket { + rx_data: &mut rx_data, + }, + }; + + let submit_status = unsafe { ((*tcp4).receive)(tcp4, &mut token) }; + write_prefixed_status(label, "_rx_submit_status", submit_status); + let completion = if submit_status.is_error() { + submit_status + } else { + poll_tcp4(tcp4, &token.completion_token) + }; + write_prefixed_status(label, "_rx_completion", completion); + write_prefixed_status(label, "_rx_token_status", token.completion_token.status); + *received_len = rx_data.data_length as usize; + write_ascii(label); + write_ascii("_rx_len: "); + write_dec(*received_len as u64); + write_ascii("\r\n"); + if *received_len >= 5 { + write_ascii(label); + write_ascii("_rx_first5: "); + let mut i = 0usize; + while i < 5 { + write_ascii("0x"); + write_hex64(out[i] as u64); + if i + 1 < 5 { + write_ascii(","); + } + i += 1; + } + write_ascii("\r\n"); + } + unsafe { + ((*bs).close_event)(event); + } + completion +} + +fn tcp4_tls_clienthello_probe(bs: *mut EfiBootServices) -> EfiStatus { + write_ascii("tcp4_tls_probe_start\r\n"); + + let mut tls_service_count = 0usize; + let mut tls_service_handles = null_mut(); + let status = locate_protocol_handles( + bs, + &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, + &mut tls_service_count, + &mut tls_service_handles, + ); + write_status("tcp4_tls_probe_tls_service_status: ", status); + write_ascii("tcp4_tls_probe_tls_service_handle_count: "); + write_dec(tls_service_count as u64); + write_ascii("\r\n"); + if status.is_error() || tls_service_count == 0 || tls_service_handles.is_null() { + return status; + } + + let tls_service_handle = unsafe { *tls_service_handles }; + let tls_binding = match open_protocol::( + bs, + tls_service_handle, + &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, + ) { + Ok(binding) => binding, + Err(status) => { + write_status("tcp4_tls_probe_tls_binding_open_status: ", status); + unsafe { + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + return status; + } + }; + + let mut tls_child = null_mut(); + let status = unsafe { ((*tls_binding).create_child)(tls_binding, &mut tls_child) }; + write_status("tcp4_tls_probe_tls_create_child_status: ", status); + if status.is_error() || tls_child.is_null() { + unsafe { + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + return if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }; + } + + let mut clienthello = [0u8; 2048]; + let mut clienthello_len = 0usize; + let status = build_tls_clienthello_on_child( + bs, + tls_child, + &mut clienthello, + &mut clienthello_len, + "tcp4_tls_probe_tls_config", + ); + write_status("tcp4_tls_probe_build_clienthello_status: ", status); + write_ascii("tcp4_tls_probe_clienthello_len: "); + write_dec(clienthello_len as u64); + write_ascii("\r\n"); + if status.is_error() || clienthello_len == 0 || clienthello_len > clienthello.len() { + unsafe { + ((*tls_binding).destroy_child)(tls_binding, tls_child); + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + return status; + } + + let mut tcp_service_count = 0usize; + let mut tcp_service_handles = null_mut(); + let status = locate_protocol_handles( + bs, + &EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID, + &mut tcp_service_count, + &mut tcp_service_handles, + ); + write_status("tcp4_tls_probe_tcp_service_status: ", status); + write_ascii("tcp4_tls_probe_tcp_service_handle_count: "); + write_dec(tcp_service_count as u64); + write_ascii("\r\n"); + if status.is_error() || tcp_service_count == 0 || tcp_service_handles.is_null() { + unsafe { + ((*tls_binding).destroy_child)(tls_binding, tls_child); + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + return status; + } + + let tcp_service_handle = unsafe { *tcp_service_handles }; + let tcp_binding = match open_protocol::( + bs, + tcp_service_handle, + &EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID, + ) { + Ok(binding) => binding, + Err(status) => { + write_status("tcp4_tls_probe_tcp_binding_open_status: ", status); + unsafe { + ((*bs).free_pool)(tcp_service_handles as *mut c_void); + ((*tls_binding).destroy_child)(tls_binding, tls_child); + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + return status; + } + }; + + let mut tcp_child = null_mut(); + let status = unsafe { ((*tcp_binding).create_child)(tcp_binding, &mut tcp_child) }; + write_status("tcp4_tls_probe_tcp_create_child_status: ", status); + if status.is_error() || tcp_child.is_null() { + unsafe { + ((*bs).free_pool)(tcp_service_handles as *mut c_void); + ((*tls_binding).destroy_child)(tls_binding, tls_child); + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + return if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }; + } + + let tcp4 = match open_protocol::(bs, tcp_child, &EFI_TCP4_PROTOCOL_GUID) { + Ok(tcp4) => { + write_status("tcp4_tls_probe_tcp_protocol_status: ", EFI_SUCCESS); + tcp4 + } + Err(status) => { + write_status("tcp4_tls_probe_tcp_protocol_status: ", status); + unsafe { + ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); + ((*bs).free_pool)(tcp_service_handles as *mut c_void); + ((*tls_binding).destroy_child)(tls_binding, tls_child); + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + return status; + } + }; + + let mut config = EfiTcp4ConfigData { + type_of_service: 0, + time_to_live: 64, + access_point: EfiTcp4AccessPoint { + use_default_address: 1, + station_address: [0; 4], + subnet_mask: [0; 4], + station_port: 0, + remote_address: [10, 3, 10, 229], + remote_port: 3443, + active_flag: 1, + }, + control_option: EfiTcp4Option { + receive_buffer_size: 0, + send_buffer_size: 0, + max_syn_back_log: 0, + connection_timeout: 0, + data_retries: 0, + fin_timeout: 0, + time_wait_timeout: 0, + keep_alive_probes: 0, + keep_alive_time: 0, + keep_alive_interval: 0, + enable_nagle: 0, + enable_time_stamp: 0, + enable_window_scaling: 0, + enable_selective_ack: 0, + enable_path_mtu_discovery: 0, + }, + }; + let status = unsafe { ((*tcp4).configure)(tcp4, &mut config) }; + write_status("tcp4_tls_probe_tcp_configure_status: ", status); + if status.is_error() { + unsafe { + ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); + ((*bs).free_pool)(tcp_service_handles as *mut c_void); + ((*tls_binding).destroy_child)(tls_binding, tls_child); + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + return status; + } + + let mut connect_event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut connect_event, + ) + }; + write_status("tcp4_tls_probe_connect_event_status: ", status); + if status.is_error() { + unsafe { + ((*tcp4).configure)(tcp4, null_mut()); + ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); + ((*bs).free_pool)(tcp_service_handles as *mut c_void); + ((*tls_binding).destroy_child)(tls_binding, tls_child); + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + return status; + } + + let mut connect_token = EfiTcp4ConnectionToken { + completion_token: EfiTcp4CompletionToken { + event: connect_event, + status: EFI_NOT_READY, + }, + }; + let submit_status = unsafe { ((*tcp4).connect)(tcp4, &mut connect_token) }; + write_status("tcp4_tls_probe_connect_submit_status: ", submit_status); + let connect_status = if submit_status.is_error() { + submit_status + } else { + poll_tcp4(tcp4, &connect_token.completion_token) + }; + write_status("tcp4_tls_probe_connect_completion: ", connect_status); + unsafe { + ((*bs).close_event)(connect_event); + } + if connect_status.is_error() { + unsafe { + ((*tcp4).configure)(tcp4, null_mut()); + ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); + ((*bs).free_pool)(tcp_service_handles as *mut c_void); + ((*tls_binding).destroy_child)(tls_binding, tls_child); + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + return connect_status; + } + + let tx_status = tcp4_transmit_once( + bs, + tcp4, + &mut clienthello[..clienthello_len], + "tcp4_tls_probe", + ); + let mut rx = [0u8; 2048]; + let mut rx_len = 0usize; + let rx_status = if tx_status.is_error() { + tx_status + } else { + tcp4_receive_once(bs, tcp4, &mut rx, &mut rx_len, "tcp4_tls_probe") + }; + write_status("tcp4_tls_probe_result: ", rx_status); + + unsafe { + ((*tcp4).configure)(tcp4, null_mut()); + ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); + ((*bs).free_pool)(tcp_service_handles as *mut c_void); + ((*tls_binding).destroy_child)(tls_binding, tls_child); + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + rx_status +} + +fn run_tcp4_probe(bs: *mut EfiBootServices) -> EfiStatus { + write_ascii("tcp4_probe_start\r\n"); + let mut service_count = 0usize; + let mut service_handles = null_mut(); + let status = locate_protocol_handles( + bs, + &EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID, + &mut service_count, + &mut service_handles, + ); + write_status("tcp4_probe_service_status: ", status); + write_ascii("tcp4_probe_service_handle_count: "); + write_dec(service_count as u64); + write_ascii("\r\n"); + if status.is_error() || service_count == 0 || service_handles.is_null() { + return status; + } + + let remote = [10, 3, 10, 229]; + let mut result = EFI_NOT_FOUND; + let mut i = 0usize; + while i < service_count { + let service_handle = unsafe { *service_handles.add(i) }; + let binding = match open_protocol::( + bs, + service_handle, + &EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID, + ) { + Ok(binding) => binding, + Err(status) => { + write_status("tcp4_probe_binding_open_status: ", status); + i += 1; + continue; + } + }; + + result = tcp4_connect_probe(bs, binding, remote, 3443, "tcp4_probe_3443"); + if !result.is_error() { + break; + } + + result = tcp4_connect_probe(bs, binding, remote, 443, "tcp4_probe_443"); + if !result.is_error() { + break; + } + + i += 1; + } + + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } + write_status("tcp4_probe_result: ", result); + result +} diff --git a/loongarch64-uefi-loader/src/tls.rs b/loongarch64-uefi-loader/src/tls.rs new file mode 100644 index 00000000..4430907a --- /dev/null +++ b/loongarch64-uefi-loader/src/tls.rs @@ -0,0 +1,436 @@ +static HTTPS_CA_PEM: &[u8] = b"-----BEGIN CERTIFICATE-----\n\ +MIIDHjCCAgagAwIBAgIUBJubHQIousJm3ZT9sNPYq0u1AhwwDQYJKoZIhvcNAQEL\n\ +BQAwFjEUMBIGA1UEAwwLMTAuMy4xMC4yMjkwHhcNMjYwNTEzMDkxMTIwWhcNMjYw\n\ +NTIwMDkxMTIwWjAWMRQwEgYDVQQDDAsxMC4zLjEwLjIyOTCCASIwDQYJKoZIhvcN\n\ +AQEBBQADggEPADCCAQoCggEBALb3klUcff8fXYIcsgeQr1gs2rnwbOl/4Unwtulx\n\ +wG1K8joXYwWT4NP4XSOJy8aVuLk0FSd8VB29l6gjduSYzdC1CE9i3bzJnu4E96X/\n\ +EqRWP6QPkQJUizpH3qwxK1sDNJTmoAdq48v3cLgyyDdxzU/iVlWM51izk4njFMzZ\n\ +4PCLFfznANnj8o5diDCQ96uyKxmaXArIeDAAwcTSlJYc7QHWg6WEg+FQcn3TaMKJ\n\ +8rNELrKMrygc71ZdF9r6anud4YMouse6wJmEzGEVSCQ/y3dxd8gr1Ixq3DV9Yj9J\n\ +fZ57GWjWLTi1CWyMAAod8b6xr+o2yHRS2mGIfTEskTHTc+8CAwEAAaNkMGIwHQYD\n\ +VR0OBBYEFIimL7eY9PEocEUee1gz/YxTalmbMB8GA1UdIwQYMBaAFIimL7eY9PEo\n\ +cEUee1gz/YxTalmbMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0RBAgwBocECgMK5TAN\n\ +BgkqhkiG9w0BAQsFAAOCAQEAf1TkdDogQAYDgSUdraZ6WtOrD7MrLH69DZIcMrVf\n\ +GymOgar70uD9s1MEAwAsCgfqN8+kRcR/viWY8e86AzYVralqiLVs9tpR+vrnFejd\n\ +f9KLftc3owFwmiMLR5szwZMENOz2F+TJ8fNZBTXaJuITxrcIwuBym0FqL1pkN4hL\n\ +ikfU5paqfDst5LA/Wu/56XPtP8tFGh498jNsKlAumlQgaX0w+xxGiaGf1WkvTOP8\n\ +bVwyUYVeTIG2utpOKra0gkg42qcPdvRzZsT9REzlp2cxyBx5fkSmS0kXtqg4fT69\n\ +9/dZPxTWismXdZ4HN74kKak5tAB9CwKXvwaLRqOmXEg4hw==\n\ +-----END CERTIFICATE-----\n"; + +fn b64_value(ch: u8) -> Option { + match ch { + b'A'..=b'Z' => Some(ch - b'A'), + b'a'..=b'z' => Some(ch - b'a' + 26), + b'0'..=b'9' => Some(ch - b'0' + 52), + b'+' => Some(62), + b'/' => Some(63), + _ => None, + } +} + +fn pem_to_der(pem: &[u8], out: &mut [u8]) -> Result { + let mut in_body = false; + let mut accum = 0u32; + let mut bits = 0u32; + let mut len = 0usize; + let mut i = 0usize; + while i < pem.len() { + let ch = pem[i]; + if !in_body { + if ch == b'\n' { + in_body = true; + } + i += 1; + continue; + } + if ch == b'-' { + break; + } + if ch == b'=' { + break; + } + if let Some(value) = b64_value(ch) { + accum = (accum << 6) | value as u32; + bits += 6; + while bits >= 8 { + bits -= 8; + if len >= out.len() { + return Err(EFI_BUFFER_TOO_SMALL); + } + out[len] = ((accum >> bits) & 0xff) as u8; + len += 1; + } + } + i += 1; + } + Ok(len) +} + +fn set_tls_ca_variants(tls_config: *mut EfiTlsConfigurationProtocol, label: &str) { + let set_pem_status = unsafe { + ((*tls_config).set_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + HTTPS_CA_PEM.as_ptr() as *mut c_void, + HTTPS_CA_PEM.len(), + ) + }; + if VERBOSE_SETUP_LOGS { + if label == "tls_config" { + write_status("tls_config_set_ca_status: ", set_pem_status); + } else { + write_ascii(label); + write_ascii("_set_ca_pem_status: 0x"); + write_hex64(set_pem_status.0); + write_ascii("\r\n"); + } + } + + let mut der = [0u8; 1536]; + match pem_to_der(HTTPS_CA_PEM, &mut der) { + Ok(der_len) => { + let set_der_status = unsafe { + ((*tls_config).set_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + der.as_mut_ptr() as *mut c_void, + der_len, + ) + }; + if VERBOSE_SETUP_LOGS { + write_ascii(label); + write_ascii("_ca_der_size: "); + write_dec(der_len as u64); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_set_ca_der_status: 0x"); + write_hex64(set_der_status.0); + write_ascii("\r\n"); + } + } + Err(status) => { + if VERBOSE_SETUP_LOGS { + write_ascii(label); + write_ascii("_ca_der_decode_status: 0x"); + write_hex64(status.0); + write_ascii("\r\n"); + } + } + } +} + +fn configure_tls_ca(bs: *mut EfiBootServices) { + let mut service_count = 0usize; + let mut service_handles = null_mut(); + let status = locate_protocol_handles( + bs, + &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, + &mut service_count, + &mut service_handles, + ); + if VERBOSE_SETUP_LOGS { + write_status("tls_config_service_status: ", status); + write_ascii("tls_config_service_handle_count: "); + write_dec(service_count as u64); + write_ascii("\r\n"); + } + if status.is_error() || service_count == 0 || service_handles.is_null() { + return; + } + + let service_handle = unsafe { *service_handles }; + let binding = match open_protocol::( + bs, + service_handle, + &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, + ) { + Ok(binding) => { + if VERBOSE_SETUP_LOGS { + write_status("tls_config_binding_open_status: ", EFI_SUCCESS); + } + binding + } + Err(status) => { + if VERBOSE_SETUP_LOGS { + write_status("tls_config_binding_open_status: ", status); + } + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } + return; + } + }; + + let mut child = null_mut(); + let status = unsafe { ((*binding).create_child)(binding, &mut child) }; + if VERBOSE_SETUP_LOGS { + write_status("tls_config_create_child_status: ", status); + } + if status.is_error() || child.is_null() { + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } + return; + } + + match open_protocol::( + bs, + child, + &EFI_TLS_CONFIGURATION_PROTOCOL_GUID, + ) { + Ok(tls_config) => { + if VERBOSE_SETUP_LOGS { + write_status("tls_config_protocol_status: ", EFI_SUCCESS); + } + let mut ca_size = 0usize; + let get_status = unsafe { + ((*tls_config).get_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + null_mut(), + &mut ca_size, + ) + }; + if VERBOSE_SETUP_LOGS { + write_status("tls_config_get_ca_status: ", get_status); + write_ascii("tls_config_get_ca_size: "); + write_dec(ca_size as u64); + write_ascii("\r\n"); + } + + set_tls_ca_variants(tls_config, "tls_config"); + + ca_size = 0; + let get_after_status = unsafe { + ((*tls_config).get_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + null_mut(), + &mut ca_size, + ) + }; + if VERBOSE_SETUP_LOGS { + write_status("tls_config_get_ca_after_status: ", get_after_status); + write_ascii("tls_config_get_ca_after_size: "); + write_dec(ca_size as u64); + write_ascii("\r\n"); + } + } + Err(status) => { + if VERBOSE_SETUP_LOGS { + write_status("tls_config_protocol_status: ", status); + } + } + } + + let destroy_status = unsafe { ((*binding).destroy_child)(binding, child) }; + if VERBOSE_SETUP_LOGS { + write_status("tls_config_destroy_child_status: ", destroy_status); + } + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } +} + +fn configure_tls_ca_on_handle(bs: *mut EfiBootServices, handle: EfiHandle, label: &str) { + match open_protocol::( + bs, + handle, + &EFI_TLS_CONFIGURATION_PROTOCOL_GUID, + ) { + Ok(tls_config) => { + if VERBOSE_SETUP_LOGS { + write_ascii(label); + write_ascii("_protocol_status: 0x"); + write_hex64(EFI_SUCCESS.0); + write_ascii("\r\n"); + } + + let mut ca_size = 0usize; + let get_status = unsafe { + ((*tls_config).get_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + null_mut(), + &mut ca_size, + ) + }; + if VERBOSE_SETUP_LOGS { + write_ascii(label); + write_ascii("_get_ca_status: 0x"); + write_hex64(get_status.0); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_get_ca_size: "); + write_dec(ca_size as u64); + write_ascii("\r\n"); + } + + set_tls_ca_variants(tls_config, label); + + ca_size = 0; + let get_after_status = unsafe { + ((*tls_config).get_data)( + tls_config, + EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, + null_mut(), + &mut ca_size, + ) + }; + if VERBOSE_SETUP_LOGS { + write_ascii(label); + write_ascii("_get_ca_after_status: 0x"); + write_hex64(get_after_status.0); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_get_ca_after_size: "); + write_dec(ca_size as u64); + write_ascii("\r\n"); + } + } + Err(status) => { + if VERBOSE_SETUP_LOGS { + write_ascii(label); + write_ascii("_protocol_status: 0x"); + write_hex64(status.0); + write_ascii("\r\n"); + } + } + } +} + +fn tls_set_u32(tls: *mut EfiTlsProtocol, data_type: u32, value: &mut u32) -> EfiStatus { + unsafe { + ((*tls).set_session_data)( + tls, + data_type, + value as *mut u32 as *mut c_void, + core::mem::size_of::(), + ) + } +} + +fn build_tls_clienthello_on_child( + bs: *mut EfiBootServices, + child: EfiHandle, + out: &mut [u8], + out_len: &mut usize, + label: &str, +) -> EfiStatus { + configure_tls_ca_on_handle(bs, child, label); + + let tls = match open_protocol::(bs, child, &EFI_TLS_PROTOCOL_GUID) { + Ok(tls) => { + write_status("tls_probe_protocol_status: ", EFI_SUCCESS); + tls + } + Err(status) => { + write_status("tls_probe_protocol_status: ", status); + return status; + } + }; + + let mut connection_end = EFI_TLS_CONNECTION_END_CLIENT; + let status = tls_set_u32( + tls, + EFI_TLS_SESSION_DATA_TYPE_CONNECTION_END, + &mut connection_end, + ); + write_status("tls_probe_set_connection_end_status: ", status); + + let mut verify = EFI_TLS_VERIFY_NONE; + let status = tls_set_u32(tls, EFI_TLS_SESSION_DATA_TYPE_VERIFY_METHOD, &mut verify); + write_status("tls_probe_set_verify_status: ", status); + + let mut version = EfiTlsVersion { major: 3, minor: 3 }; + let status = unsafe { + ((*tls).set_session_data)( + tls, + EFI_TLS_SESSION_DATA_TYPE_VERSION, + &mut version as *mut EfiTlsVersion as *mut c_void, + core::mem::size_of::(), + ) + }; + write_status("tls_probe_set_version_status: ", status); + + *out_len = out.len(); + unsafe { ((*tls).build_response_packet)(tls, null_mut(), 0, out.as_mut_ptr(), out_len) } +} + +fn run_tls_clienthello_probe(bs: *mut EfiBootServices) -> EfiStatus { + write_ascii("tls_probe_start\r\n"); + let mut service_count = 0usize; + let mut service_handles = null_mut(); + let status = locate_protocol_handles( + bs, + &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, + &mut service_count, + &mut service_handles, + ); + write_status("tls_probe_service_status: ", status); + write_ascii("tls_probe_service_handle_count: "); + write_dec(service_count as u64); + write_ascii("\r\n"); + if status.is_error() || service_count == 0 || service_handles.is_null() { + return status; + } + + let service_handle = unsafe { *service_handles }; + let binding = match open_protocol::( + bs, + service_handle, + &EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID, + ) { + Ok(binding) => binding, + Err(status) => { + write_status("tls_probe_binding_open_status: ", status); + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } + return status; + } + }; + + let mut child = null_mut(); + let status = unsafe { ((*binding).create_child)(binding, &mut child) }; + write_status("tls_probe_create_child_status: ", status); + if status.is_error() || child.is_null() { + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } + return if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }; + } + + let mut out = [0u8; 2048]; + let mut out_len = 0usize; + let status = + build_tls_clienthello_on_child(bs, child, &mut out, &mut out_len, "tls_probe_config"); + write_status("tls_probe_build_clienthello_status: ", status); + write_ascii("tls_probe_clienthello_len: "); + write_dec(out_len as u64); + write_ascii("\r\n"); + if out_len >= 5 { + write_ascii("tls_probe_clienthello_first5: "); + let mut i = 0usize; + while i < 5 { + write_ascii("0x"); + write_hex64(out[i] as u64); + if i + 1 < 5 { + write_ascii(","); + } + i += 1; + } + write_ascii("\r\n"); + } + + unsafe { + ((*binding).destroy_child)(binding, child); + ((*bs).free_pool)(service_handles as *mut c_void); + } + status +} diff --git a/loongarch64-uefi-loader/src/uefi.rs b/loongarch64-uefi-loader/src/uefi.rs new file mode 100644 index 00000000..515e6be8 --- /dev/null +++ b/loongarch64-uefi-loader/src/uefi.rs @@ -0,0 +1,91 @@ +extern "C" fn noop_event(_event: EfiEvent, _context: *mut c_void) {} + +fn poll_http(http: *mut EfiHttpProtocol, token: *const EfiHttpToken) -> EfiStatus { + let mut i = 0; + while i < HTTP_POLL_LIMIT { + let status = unsafe { read_volatile(core::ptr::addr_of!((*token).status)) }; + if status != EFI_NOT_READY { + return status; + } + unsafe { + ((*http).poll)(http); + } + i += 1; + } + unsafe { read_volatile(core::ptr::addr_of!((*token).status)) } +} + +fn warm_up_http(bs: *mut EfiBootServices, http: *mut EfiHttpProtocol) { + let mut last_poll = EFI_NOT_READY; + let mut i = 0; + while i < 20 { + unsafe { + if let Some(stall) = (*bs).stall { + stall(100_000); + } + last_poll = ((*http).poll)(http); + } + i += 1; + } + if VERBOSE_SETUP_LOGS { + write_status("http_post_configure_poll_status: ", last_poll); + } +} + +fn locate_protocol_handles( + bs: *mut EfiBootServices, + guid: &EfiGuid, + count: &mut usize, + handles: &mut *mut EfiHandle, +) -> EfiStatus { + *count = 0; + *handles = null_mut(); + unsafe { + ((*bs).locate_handle_buffer)( + EFI_LOCATE_BY_PROTOCOL, + guid as *const EfiGuid, + null_mut(), + count, + handles, + ) + } +} + +fn print_protocol_handle_count(bs: *mut EfiBootServices, label: &str, guid: &EfiGuid) { + let mut count = 0usize; + let mut handles = null_mut(); + let status = locate_protocol_handles(bs, guid, &mut count, &mut handles); + if VERBOSE_SETUP_LOGS { + write_ascii(label); + write_ascii("_status: "); + write_ascii("0x"); + write_hex64(status.0); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_handle_count: "); + write_dec(count as u64); + write_ascii("\r\n"); + } + if !status.is_error() && !handles.is_null() { + unsafe { + ((*bs).free_pool)(handles as *mut c_void); + } + } +} + +fn open_protocol( + bs: *mut EfiBootServices, + handle: EfiHandle, + guid: &EfiGuid, +) -> Result<*mut T, EfiStatus> { + let mut interface = null_mut(); + let status = unsafe { ((*bs).handle_protocol)(handle, guid as *const EfiGuid, &mut interface) }; + if status.is_error() || interface.is_null() { + return Err(if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }); + } + Ok(interface as *mut T) +} From c40e64aa98619e2bfbb07661826f57c80fe9c1b5 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Thu, 14 May 2026 07:20:04 +0000 Subject: [PATCH 24/39] feat: implement TLS handshake with process_packet and pre-receive for UEFI loader --- loongarch64-uefi-loader/src/abi.rs | 17 ++- loongarch64-uefi-loader/src/tcp4.rs | 224 ++++++++++++++++++++++++++-- 2 files changed, 229 insertions(+), 12 deletions(-) diff --git a/loongarch64-uefi-loader/src/abi.rs b/loongarch64-uefi-loader/src/abi.rs index fe1685b2..887e70ac 100644 --- a/loongarch64-uefi-loader/src/abi.rs +++ b/loongarch64-uefi-loader/src/abi.rs @@ -36,14 +36,16 @@ const KERNEL_CHUNK: usize = 16 * 1024; const MAX_KERNEL_SIZE: u64 = 256 * 1024 * 1024; const MEMORY_MAP_MAX: usize = 64 * 1024; const HTTP_POLL_LIMIT: usize = 1_000_000; -const TCP4_POLL_LIMIT: usize = 2_000_000; +const TCP4_POLL_LIMIT: usize = 5_000_000; const EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE: u32 = 2; const EFI_TLS_SESSION_DATA_TYPE_VERSION: u32 = 0; const EFI_TLS_SESSION_DATA_TYPE_CONNECTION_END: u32 = 1; const EFI_TLS_SESSION_DATA_TYPE_VERIFY_METHOD: u32 = 5; +const EFI_TLS_SESSION_DATA_TYPE_SESSION_STATE: u32 = 7; const EFI_TLS_CONNECTION_END_CLIENT: u32 = 0; const EFI_TLS_VERIFY_NONE: u32 = 0; +const EFI_TLS_SESSION_DATA_TRANSFERRING: u32 = 2; const VERBOSE_SETUP_LOGS: bool = false; #[repr(C)] @@ -253,7 +255,18 @@ struct EfiTlsProtocol { get_session_data: extern "C" fn(*mut EfiTlsProtocol, u32, *mut c_void, *mut usize) -> EfiStatus, build_response_packet: extern "C" fn(*mut EfiTlsProtocol, *mut u8, usize, *mut u8, *mut usize) -> EfiStatus, - process_packet: usize, + process_packet: extern "C" fn( + *mut EfiTlsProtocol, + *mut *mut EfiTlsFragmentData, + *mut u32, + u32, + ) -> EfiStatus, +} + +#[repr(C)] +struct EfiTlsFragmentData { + fragment_length: u32, + fragment_buffer: *mut c_void, } #[repr(C)] diff --git a/loongarch64-uefi-loader/src/tcp4.rs b/loongarch64-uefi-loader/src/tcp4.rs index 000ac53e..dbbf7174 100644 --- a/loongarch64-uefi-loader/src/tcp4.rs +++ b/loongarch64-uefi-loader/src/tcp4.rs @@ -271,7 +271,11 @@ fn tcp4_receive_once( }; write_prefixed_status(label, "_rx_completion", completion); write_prefixed_status(label, "_rx_token_status", token.completion_token.status); - *received_len = rx_data.data_length as usize; + if completion.is_error() { + *received_len = 0; + } else { + *received_len = rx_data.data_length as usize; + } write_ascii(label); write_ascii("_rx_len: "); write_dec(*received_len as u64); @@ -296,6 +300,140 @@ fn tcp4_receive_once( completion } +fn print_tcp4_first5(label: &str, suffix: &str, bytes: &[u8], len: usize) { + if len < 5 { + return; + } + write_ascii(label); + write_ascii(suffix); + let mut i = 0usize; + while i < 5 { + write_ascii("0x"); + write_hex64(bytes[i] as u64); + if i + 1 < 5 { + write_ascii(","); + } + i += 1; + } + write_ascii("\r\n"); +} + +fn tls_session_state(tls: *mut EfiTlsProtocol, label: &str) -> u32 { + let mut state = 0u32; + let mut state_len = core::mem::size_of::(); + let status = unsafe { + ((*tls).get_session_data)( + tls, + EFI_TLS_SESSION_DATA_TYPE_SESSION_STATE, + &mut state as *mut u32 as *mut c_void, + &mut state_len, + ) + }; + write_ascii(label); + write_ascii("_state_status: "); + write_ascii("0x"); + write_hex64(status.0); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_state: "); + write_dec(state as u64); + write_ascii("\r\n"); + state +} + +fn tcp4_transmit_with_pre_receive( + bs: *mut EfiBootServices, + tcp4: *mut EfiTcp4Protocol, + bytes: &mut [u8], + out: &mut [u8], + received_len: &mut usize, + label: &str, +) -> EfiStatus { + *received_len = 0; + + let mut rx_event = null_mut(); + let rx_event_status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut rx_event, + ) + }; + write_prefixed_status(label, "_pre_rx_event_status", rx_event_status); + + let mut rx_data = EfiTcp4ReceiveData { + urgent_flag: 0, + data_length: out.len() as u32, + fragment_count: 1, + fragment_table: [EfiTcp4FragmentData { + fragment_length: out.len() as u32, + fragment_buffer: out.as_mut_ptr() as *mut c_void, + }], + }; + let mut rx_token = EfiTcp4IoToken { + completion_token: EfiTcp4CompletionToken { + event: rx_event, + status: EFI_NOT_READY, + }, + packet: EfiTcp4IoPacket { + rx_data: &mut rx_data, + }, + }; + let pre_rx_submit_status = if rx_event_status.is_error() { + rx_event_status + } else { + unsafe { ((*tcp4).receive)(tcp4, &mut rx_token) } + }; + write_prefixed_status(label, "_pre_rx_submit_status", pre_rx_submit_status); + + let tx_status = tcp4_transmit_once(bs, tcp4, bytes, label); + if !tx_status.is_error() { + unsafe { + if let Some(stall) = (*bs).stall { + stall(1_000_000); + } + } + let mut warm_poll = EFI_NOT_READY; + let mut i = 0usize; + while i < 200 { + warm_poll = unsafe { ((*tcp4).poll)(tcp4) }; + i += 1; + } + write_prefixed_status(label, "_post_tx_poll_status", warm_poll); + } + + let rx_status = if tx_status.is_error() { + tx_status + } else if !pre_rx_submit_status.is_error() { + let completion = poll_tcp4(tcp4, &rx_token.completion_token); + write_prefixed_status(label, "_pre_rx_completion", completion); + write_prefixed_status(label, "_pre_rx_token_status", rx_token.completion_token.status); + if completion.is_error() { + *received_len = 0; + } else { + *received_len = rx_data.data_length as usize; + } + write_ascii(label); + write_ascii("_pre_rx_len: "); + write_dec(*received_len as u64); + write_ascii("\r\n"); + print_tcp4_first5(label, "_pre_rx_first5: ", out, *received_len); + completion + } else { + tcp4_receive_once(bs, tcp4, out, received_len, label) + }; + + unsafe { + if !rx_event.is_null() { + ((*bs).close_event)(rx_event); + } + } + + rx_status +} + fn tcp4_tls_clienthello_probe(bs: *mut EfiBootServices) -> EfiStatus { write_ascii("tcp4_tls_probe_start\r\n"); @@ -446,7 +584,7 @@ fn tcp4_tls_clienthello_probe(bs: *mut EfiBootServices) -> EfiStatus { subnet_mask: [0; 4], station_port: 0, remote_address: [10, 3, 10, 229], - remote_port: 3443, + remote_port: 443, active_flag: 1, }, control_option: EfiTcp4Option { @@ -529,19 +667,85 @@ fn tcp4_tls_clienthello_probe(bs: *mut EfiBootServices) -> EfiStatus { return connect_status; } - let tx_status = tcp4_transmit_once( + let tls = match open_protocol::(bs, tls_child, &EFI_TLS_PROTOCOL_GUID) { + Ok(tls) => { + write_status("tcp4_tls_probe_tls_protocol_reopen_status: ", EFI_SUCCESS); + tls + } + Err(status) => { + write_status("tcp4_tls_probe_tls_protocol_reopen_status: ", status); + unsafe { + ((*tcp4).configure)(tcp4, null_mut()); + ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); + ((*bs).free_pool)(tcp_service_handles as *mut c_void); + ((*tls_binding).destroy_child)(tls_binding, tls_child); + ((*bs).free_pool)(tls_service_handles as *mut c_void); + } + return status; + } + }; + tls_session_state(tls, "tcp4_tls_probe_tls_initial"); + + let mut rx = [0u8; 8192]; + let mut rx_len = 0usize; + let mut rx_status = tcp4_transmit_with_pre_receive( bs, tcp4, &mut clienthello[..clienthello_len], + &mut rx, + &mut rx_len, "tcp4_tls_probe", ); - let mut rx = [0u8; 2048]; - let mut rx_len = 0usize; - let rx_status = if tx_status.is_error() { - tx_status - } else { - tcp4_receive_once(bs, tcp4, &mut rx, &mut rx_len, "tcp4_tls_probe") - }; + + let mut tls_out = [0u8; 8192]; + let mut round = 0usize; + while !rx_status.is_error() && round < 4 { + let label = match round { + 0 => "tcp4_tls_probe_hs0", + 1 => "tcp4_tls_probe_hs1", + 2 => "tcp4_tls_probe_hs2", + _ => "tcp4_tls_probe_hs3", + }; + + tls_session_state(tls, label); + let mut tls_out_len = tls_out.len(); + let build_status = unsafe { + ((*tls).build_response_packet)( + tls, + rx.as_mut_ptr(), + rx_len, + tls_out.as_mut_ptr(), + &mut tls_out_len, + ) + }; + write_prefixed_status(label, "_build_response_status", build_status); + write_ascii(label); + write_ascii("_build_response_len: "); + write_dec(tls_out_len as u64); + write_ascii("\r\n"); + print_tcp4_first5(label, "_build_response_first5: ", &tls_out, tls_out_len); + let state = tls_session_state(tls, label); + if build_status.is_error() { + rx_status = build_status; + break; + } + if state == EFI_TLS_SESSION_DATA_TRANSFERRING { + break; + } + if tls_out_len == 0 || tls_out_len > tls_out.len() { + rx_status = EFI_NOT_READY; + break; + } + rx_status = tcp4_transmit_with_pre_receive( + bs, + tcp4, + &mut tls_out[..tls_out_len], + &mut rx, + &mut rx_len, + label, + ); + round += 1; + } write_status("tcp4_tls_probe_result: ", rx_status); unsafe { From a33a3b119a05544521fa78ad948bb465f9b03b42 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Thu, 14 May 2026 08:08:51 +0000 Subject: [PATCH 25/39] feat: implement TLS encrypt/decrypt for application data in UEFI loader --- loongarch64-uefi-loader/src/abi.rs | 2 + loongarch64-uefi-loader/src/tcp4.rs | 176 ++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) diff --git a/loongarch64-uefi-loader/src/abi.rs b/loongarch64-uefi-loader/src/abi.rs index 887e70ac..49031264 100644 --- a/loongarch64-uefi-loader/src/abi.rs +++ b/loongarch64-uefi-loader/src/abi.rs @@ -46,6 +46,8 @@ const EFI_TLS_SESSION_DATA_TYPE_SESSION_STATE: u32 = 7; const EFI_TLS_CONNECTION_END_CLIENT: u32 = 0; const EFI_TLS_VERIFY_NONE: u32 = 0; const EFI_TLS_SESSION_DATA_TRANSFERRING: u32 = 2; +const EFI_TLS_ENCRYPT: u32 = 0; +const EFI_TLS_DECRYPT: u32 = 1; const VERBOSE_SETUP_LOGS: bool = false; #[repr(C)] diff --git a/loongarch64-uefi-loader/src/tcp4.rs b/loongarch64-uefi-loader/src/tcp4.rs index dbbf7174..2a655b59 100644 --- a/loongarch64-uefi-loader/src/tcp4.rs +++ b/loongarch64-uefi-loader/src/tcp4.rs @@ -341,6 +341,117 @@ fn tls_session_state(tls: *mut EfiTlsProtocol, label: &str) -> u32 { state } +fn print_ascii_prefix(label: &str, bytes: &[u8], len: usize) { + let mut count = len; + if count > 64 { + count = 64; + } + write_ascii(label); + write_ascii("_ascii_prefix: "); + let mut i = 0usize; + while i < count { + let b = bytes[i]; + if b == b'\r' { + write_ascii("\\r"); + } else if b == b'\n' { + write_ascii("\\n"); + } else if b >= 0x20 && b < 0x7f { + write_bytes(&[b]); + } else { + write_ascii("."); + } + i += 1; + } + write_ascii("\r\n"); +} + +fn build_tls_plaintext_record(out: &mut [u8], payload: &[u8]) -> usize { + if out.len() < payload.len() + 5 || payload.len() > 0xffff { + return 0; + } + out[0] = 23; + out[1] = 3; + out[2] = 3; + // UEFI TLS ProcessPacket(EfiTlsEncrypt) consumes TLS_RECORD_HEADER as a + // firmware struct, so the plaintext input Length field is host-endian. + out[3] = (payload.len() & 0xff) as u8; + out[4] = ((payload.len() >> 8) & 0xff) as u8; + let mut i = 0usize; + while i < payload.len() { + out[5 + i] = payload[i]; + i += 1; + } + payload.len() + 5 +} + +fn tls_record_total_len(bytes: &[u8], len: usize) -> usize { + if len < 5 { + return len; + } + let payload_len = ((bytes[3] as usize) << 8) | bytes[4] as usize; + let total_len = payload_len + 5; + if total_len <= len { + total_len + } else { + len + } +} + +fn tls_process_single_fragment( + tls: *mut EfiTlsProtocol, + bytes: &mut [u8], + len: usize, + process_type: u32, + label: &str, +) -> (EfiStatus, usize, *mut c_void) { + let mut fragment = EfiTlsFragmentData { + fragment_length: len as u32, + fragment_buffer: bytes.as_mut_ptr() as *mut c_void, + }; + let mut fragment_ptr = &mut fragment as *mut EfiTlsFragmentData; + let mut fragment_count = 1u32; + let status = unsafe { + ((*tls).process_packet)(tls, &mut fragment_ptr, &mut fragment_count, process_type) + }; + write_prefixed_status(label, "_process_status", status); + write_ascii(label); + write_ascii("_process_fragment_count: "); + write_dec(fragment_count as u64); + write_ascii("\r\n"); + let fragment_len = if status.is_error() || fragment_ptr.is_null() { + 0 + } else { + unsafe { (*fragment_ptr).fragment_length as usize } + }; + write_ascii(label); + write_ascii("_process_len: "); + write_dec(fragment_len as u64); + write_ascii("\r\n"); + let fragment_buffer = if status.is_error() || fragment_ptr.is_null() { + null_mut() + } else { + unsafe { (*fragment_ptr).fragment_buffer } + }; + (status, fragment_len, fragment_buffer) +} + +fn copy_from_ptr(out: &mut [u8], src: *mut c_void, len: usize) -> usize { + if src.is_null() { + return 0; + } + let mut count = len; + if count > out.len() { + count = out.len(); + } + let bytes = src as *const u8; + let mut i = 0usize; + while i < count { + out[i] = unsafe { read_volatile(bytes.add(i)) }; + i += 1; + } + count +} + fn tcp4_transmit_with_pre_receive( bs: *mut EfiBootServices, tcp4: *mut EfiTcp4Protocol, @@ -746,6 +857,71 @@ fn tcp4_tls_clienthello_probe(bs: *mut EfiBootServices) -> EfiStatus { ); round += 1; } + let final_state = tls_session_state(tls, "tcp4_tls_probe_tls_final"); + if !rx_status.is_error() && final_state == EFI_TLS_SESSION_DATA_TRANSFERRING { + let http_get = b"GET /boot/boards/loongchip-httpboot-smoke/current/manifest.json HTTP/1.0\r\nHost: 10.3.10.229\r\nConnection: close\r\n\r\n"; + let mut plain_record = [0u8; 1024]; + let plain_record_len = build_tls_plaintext_record(&mut plain_record, http_get); + write_ascii("tcp4_tls_probe_app_plain_record_len: "); + write_dec(plain_record_len as u64); + write_ascii("\r\n"); + if plain_record_len == 0 { + rx_status = EFI_BUFFER_TOO_SMALL; + } else { + let (encrypt_status, encrypted_len, encrypted_ptr) = tls_process_single_fragment( + tls, + &mut plain_record, + plain_record_len, + EFI_TLS_ENCRYPT, + "tcp4_tls_probe_app_encrypt", + ); + rx_status = encrypt_status; + if !rx_status.is_error() && encrypted_len > 0 { + let mut encrypted = [0u8; 2048]; + let encrypted_len = copy_from_ptr(&mut encrypted, encrypted_ptr, encrypted_len); + let encrypted_wire_len = tls_record_total_len(&encrypted, encrypted_len); + write_ascii("tcp4_tls_probe_app_encrypt_wire_len: "); + write_dec(encrypted_wire_len as u64); + write_ascii("\r\n"); + print_tcp4_first5( + "tcp4_tls_probe_app_encrypt", + "_first5: ", + &encrypted, + encrypted_wire_len, + ); + let mut encrypted_rx = [0u8; 8192]; + let mut encrypted_rx_len = 0usize; + rx_status = tcp4_transmit_with_pre_receive( + bs, + tcp4, + &mut encrypted[..encrypted_wire_len], + &mut encrypted_rx, + &mut encrypted_rx_len, + "tcp4_tls_probe_app", + ); + if !rx_status.is_error() { + let (decrypt_status, decrypted_len, decrypted_ptr) = + tls_process_single_fragment( + tls, + &mut encrypted_rx, + encrypted_rx_len, + EFI_TLS_DECRYPT, + "tcp4_tls_probe_app_decrypt", + ); + rx_status = decrypt_status; + if !rx_status.is_error() && decrypted_len > 0 { + let mut decrypted = [0u8; 512]; + let decrypted_len = copy_from_ptr(&mut decrypted, decrypted_ptr, decrypted_len); + print_ascii_prefix( + "tcp4_tls_probe_app_decrypt", + &decrypted, + decrypted_len, + ); + } + } + } + } + } write_status("tcp4_tls_probe_result: ", rx_status); unsafe { From 77b66a8486b15ccb6cfd40873b27caace54ef76c Mon Sep 17 00:00:00 2001 From: Josen-B Date: Fri, 15 May 2026 02:32:12 +0000 Subject: [PATCH 26/39] feat: implement raw TCP4 HTTPS GET for kernel download with TLS in UEFI loader --- loongarch64-uefi-loader/src/abi.rs | 6 +- loongarch64-uefi-loader/src/tcp4.rs | 860 ++++++++++++++++++++++++++-- 2 files changed, 803 insertions(+), 63 deletions(-) diff --git a/loongarch64-uefi-loader/src/abi.rs b/loongarch64-uefi-loader/src/abi.rs index 49031264..133afd71 100644 --- a/loongarch64-uefi-loader/src/abi.rs +++ b/loongarch64-uefi-loader/src/abi.rs @@ -19,7 +19,8 @@ const EFI_NOT_READY: EfiStatus = EfiStatus(EFI_ERROR_BIT | 6); const EFI_DEVICE_ERROR: EfiStatus = EfiStatus(EFI_ERROR_BIT | 7); const EFI_NOT_FOUND: EfiStatus = EfiStatus(EFI_ERROR_BIT | 14); -const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 0; +const EFI_ALLOCATE_ANY_PAGES: EfiAllocateType = 0; +const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 2; const EFI_LOADER_DATA: EfiMemoryType = 2; const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; const EVT_NOTIFY_SIGNAL: u32 = 0x0000_0200; @@ -33,10 +34,13 @@ const HTTP_STATUS_200_OK: u32 = 3; const MANIFEST_MAX: usize = 4096; const URL16_MAX: usize = 1024; const KERNEL_CHUNK: usize = 16 * 1024; +const TLS_RX_MAX: usize = 64 * 1024; const MAX_KERNEL_SIZE: u64 = 256 * 1024 * 1024; const MEMORY_MAP_MAX: usize = 64 * 1024; const HTTP_POLL_LIMIT: usize = 1_000_000; const TCP4_POLL_LIMIT: usize = 5_000_000; +const KERNEL_TCP4_POLL_LIMIT: usize = 50_000_000; +const KERNEL_TCP4_RX_RETRIES: usize = 4; const EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE: u32 = 2; const EFI_TLS_SESSION_DATA_TYPE_VERSION: u32 = 0; diff --git a/loongarch64-uefi-loader/src/tcp4.rs b/loongarch64-uefi-loader/src/tcp4.rs index 2a655b59..a70b7426 100644 --- a/loongarch64-uefi-loader/src/tcp4.rs +++ b/loongarch64-uefi-loader/src/tcp4.rs @@ -1,3 +1,5 @@ +const KERNEL_TRACE_RECORDS: bool = false; + fn poll_tcp4(tcp4: *mut EfiTcp4Protocol, token: *const EfiTcp4CompletionToken) -> EfiStatus { let mut i = 0usize; while i < TCP4_POLL_LIMIT { @@ -13,6 +15,25 @@ fn poll_tcp4(tcp4: *mut EfiTcp4Protocol, token: *const EfiTcp4CompletionToken) - unsafe { read_volatile(core::ptr::addr_of!((*token).status)) } } +fn poll_tcp4_limit( + tcp4: *mut EfiTcp4Protocol, + token: *const EfiTcp4CompletionToken, + limit: usize, +) -> EfiStatus { + let mut i = 0usize; + while i < limit { + let status = unsafe { read_volatile(core::ptr::addr_of!((*token).status)) }; + if status != EFI_NOT_READY { + return status; + } + unsafe { + ((*tcp4).poll)(tcp4); + } + i += 1; + } + unsafe { read_volatile(core::ptr::addr_of!((*token).status)) } +} + fn tcp4_connect_probe( bs: *mut EfiBootServices, binding: *mut EfiServiceBindingProtocol, @@ -365,6 +386,107 @@ fn print_ascii_prefix(label: &str, bytes: &[u8], len: usize) { write_ascii("\r\n"); } +fn find_http_body_offset(bytes: &[u8], len: usize) -> Option { + let mut i = 0usize; + while i + 3 < len { + if bytes[i] == b'\r' + && bytes[i + 1] == b'\n' + && bytes[i + 2] == b'\r' + && bytes[i + 3] == b'\n' + { + return Some(i + 4); + } + i += 1; + } + None +} + +fn find_http_status_offset(bytes: &[u8], len: usize) -> Option { + let mut i = 0usize; + while i + 11 < len { + if bytes[i] == b'H' + && bytes[i + 1] == b'T' + && bytes[i + 2] == b'T' + && bytes[i + 3] == b'P' + && bytes[i + 4] == b'/' + { + return Some(i); + } + i += 1; + } + None +} + +fn http_response_status_is_200(bytes: &[u8], len: usize) -> bool { + match find_http_status_offset(bytes, len) { + Some(offset) => { + offset + 11 < len + && bytes[offset + 8] == b' ' + && bytes[offset + 9] == b'2' + && bytes[offset + 10] == b'0' + && bytes[offset + 11] == b'0' + } + None => false, + } +} + +fn https_path_from_url<'a>(url: &'a [u8]) -> Result<&'a [u8], EfiStatus> { + const HTTPS_PREFIX: &[u8] = b"https://"; + if !starts_with(url, HTTPS_PREFIX) { + return Err(EFI_UNSUPPORTED); + } + let mut i = HTTPS_PREFIX.len(); + while i < url.len() { + if url[i] == b'/' { + return Ok(&url[i..]); + } + i += 1; + } + Err(EFI_UNSUPPORTED) +} + +fn build_http_get_request(path: &[u8], connection: &[u8], out: &mut [u8]) -> Result { + const PREFIX: &[u8] = b"GET "; + const VERSION_HOST: &[u8] = b" HTTP/1.1\r\nHost: 10.3.10.229\r\nConnection: "; + const SUFFIX: &[u8] = b"\r\n\r\n"; + let needed = PREFIX.len() + path.len() + VERSION_HOST.len() + connection.len() + SUFFIX.len(); + if needed > out.len() { + return Err(EFI_BUFFER_TOO_SMALL); + } + let mut n = 0usize; + let mut i = 0usize; + while i < PREFIX.len() { + out[n] = PREFIX[i]; + n += 1; + i += 1; + } + i = 0; + while i < path.len() { + out[n] = path[i]; + n += 1; + i += 1; + } + i = 0; + while i < VERSION_HOST.len() { + out[n] = VERSION_HOST[i]; + n += 1; + i += 1; + } + i = 0; + while i < connection.len() { + out[n] = connection[i]; + n += 1; + i += 1; + } + i = 0; + while i < SUFFIX.len() { + out[n] = SUFFIX[i]; + n += 1; + i += 1; + } + Ok(n) +} + fn build_tls_plaintext_record(out: &mut [u8], payload: &[u8]) -> usize { if out.len() < payload.len() + 5 || payload.len() > 0xffff { return 0; @@ -397,6 +519,636 @@ fn tls_record_total_len(bytes: &[u8], len: usize) -> usize { } } +fn tls_record_declared_len(bytes: &[u8], len: usize) -> Option { + if len < 5 { + return None; + } + if bytes[0] != 23 || bytes[1] != 3 || bytes[2] != 3 { + return None; + } + Some((((bytes[3] as usize) << 8) | bytes[4] as usize) + 5) +} + +fn find_tls_app_record_start(bytes: &[u8], len: usize) -> Option { + let mut i = 0usize; + while i + 4 < len { + if bytes[i] == 23 && bytes[i + 1] == 3 && bytes[i + 2] == 3 { + return Some(i); + } + i += 1; + } + None +} + +fn tcp4_receive_kernel_once( + bs: *mut EfiBootServices, + tcp4: *mut EfiTcp4Protocol, + out: &mut [u8], + received_len: &mut usize, + verbose: bool, +) -> EfiStatus { + *received_len = 0; + let mut last_status = EFI_NOT_READY; + let mut attempt = 0usize; + while attempt < KERNEL_TCP4_RX_RETRIES { + if verbose { + write_ascii("tcp4_tls_probe_kernel_rx_attempt: "); + write_dec(attempt as u64); + write_ascii("\r\n"); + } + + let mut event = null_mut(); + let event_status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut event, + ) + }; + if verbose || event_status.is_error() { + write_status("tcp4_tls_probe_kernel_rx_event_status: ", event_status); + } + if event_status.is_error() { + return event_status; + } + + let mut rx_data = EfiTcp4ReceiveData { + urgent_flag: 0, + data_length: out.len() as u32, + fragment_count: 1, + fragment_table: [EfiTcp4FragmentData { + fragment_length: out.len() as u32, + fragment_buffer: out.as_mut_ptr() as *mut c_void, + }], + }; + let mut token = EfiTcp4IoToken { + completion_token: EfiTcp4CompletionToken { + event, + status: EFI_NOT_READY, + }, + packet: EfiTcp4IoPacket { + rx_data: &mut rx_data, + }, + }; + + let submit_status = unsafe { ((*tcp4).receive)(tcp4, &mut token) }; + if verbose || submit_status.is_error() { + write_status("tcp4_tls_probe_kernel_rx_submit_status: ", submit_status); + } + let completion = if submit_status.is_error() { + submit_status + } else { + unsafe { + if let Some(stall) = (*bs).stall { + stall(1_000_000); + } + } + poll_tcp4_limit(tcp4, &token.completion_token, KERNEL_TCP4_POLL_LIMIT) + }; + if verbose || completion.is_error() { + write_status("tcp4_tls_probe_kernel_rx_completion: ", completion); + write_status( + "tcp4_tls_probe_kernel_rx_token_status: ", + token.completion_token.status, + ); + } + + if completion.is_error() { + *received_len = 0; + last_status = completion; + } else { + *received_len = rx_data.data_length as usize; + if verbose { + write_ascii("tcp4_tls_probe_kernel_rx_len: "); + write_dec(*received_len as u64); + write_ascii("\r\n"); + print_tcp4_first5( + "tcp4_tls_probe_kernel_rx", + "_first5: ", + out, + *received_len, + ); + } + unsafe { + ((*bs).close_event)(event); + } + return completion; + } + + unsafe { + ((*bs).close_event)(event); + } + unsafe { + if let Some(stall) = (*bs).stall { + stall(200_000); + } + } + attempt += 1; + } + last_status +} + +fn https_send_get_with_pre_receive( + bs: *mut EfiBootServices, + tcp4: *mut EfiTcp4Protocol, + tls: *mut EfiTlsProtocol, + request: &[u8], + encrypted_rx: &mut [u8], + encrypted_rx_len: &mut usize, + label: &str, +) -> EfiStatus { + let mut plain_record = [0u8; 1536]; + let plain_record_len = build_tls_plaintext_record(&mut plain_record, request); + write_ascii(label); + write_ascii("_plain_record_len: "); + write_dec(plain_record_len as u64); + write_ascii("\r\n"); + if plain_record_len == 0 { + return EFI_BUFFER_TOO_SMALL; + } + + let (encrypt_status, encrypted_len, encrypted_ptr) = + tls_process_single_fragment(tls, &mut plain_record, plain_record_len, EFI_TLS_ENCRYPT, label); + if encrypt_status.is_error() || encrypted_len == 0 { + return encrypt_status; + } + + let mut encrypted = [0u8; 2048]; + let encrypted_len = copy_from_ptr(&mut encrypted, encrypted_ptr, encrypted_len); + let encrypted_wire_len = tls_record_total_len(&encrypted, encrypted_len); + write_ascii(label); + write_ascii("_wire_len: "); + write_dec(encrypted_wire_len as u64); + write_ascii("\r\n"); + + tcp4_transmit_with_pre_receive( + bs, + tcp4, + &mut encrypted[..encrypted_wire_len], + encrypted_rx, + encrypted_rx_len, + label, + ) +} + +fn https_get_manifest_probe( + bs: *mut EfiBootServices, + tcp4: *mut EfiTcp4Protocol, + tls: *mut EfiTlsProtocol, + rx_status: &mut EfiStatus, +) -> Option { + if rx_status.is_error() { + return None; + } + + let final_state = tls_session_state(tls, "tcp4_tls_probe_tls_final"); + if final_state != EFI_TLS_SESSION_DATA_TRANSFERRING { + return None; + } + + let mut http_get = [0u8; 512]; + let http_get_len = match build_http_get_request( + b"/boot/boards/loongchip-httpboot-smoke/current/manifest.json", + b"keep-alive", + &mut http_get, + ) { + Ok(len) => len, + Err(status) => { + *rx_status = status; + return None; + } + }; + + let mut encrypted_rx = [0u8; TLS_RX_MAX]; + let mut encrypted_rx_len = 0usize; + *rx_status = https_send_get_with_pre_receive( + bs, + tcp4, + tls, + &http_get[..http_get_len], + &mut encrypted_rx, + &mut encrypted_rx_len, + "tcp4_tls_probe_app", + ); + if rx_status.is_error() { + return None; + } + + let mut http_plain = [0u8; MANIFEST_MAX + 1024]; + let mut http_len = 0usize; + let mut loop_count = 0usize; + loop { + let (decrypt_status, decrypted_len, decrypted_ptr) = tls_process_single_fragment( + tls, + &mut encrypted_rx, + encrypted_rx_len, + EFI_TLS_DECRYPT, + "tcp4_tls_probe_app_decrypt", + ); + *rx_status = decrypt_status; + if rx_status.is_error() { + return None; + } + if decrypted_len > 0 { + let mut decrypted = [0u8; 1024]; + let decrypted_len = copy_from_ptr(&mut decrypted, decrypted_ptr, decrypted_len); + if loop_count == 0 { + print_ascii_prefix("tcp4_tls_probe_app_decrypt", &decrypted, decrypted_len); + } + if http_len + decrypted_len > http_plain.len() { + *rx_status = EFI_BUFFER_TOO_SMALL; + return None; + } + let mut i = 0usize; + while i < decrypted_len { + http_plain[http_len + i] = decrypted[i]; + i += 1; + } + http_len += decrypted_len; + } + + if let Some(body_offset) = find_http_body_offset(&http_plain, http_len) { + let body_len = http_len - body_offset; + write_ascii("tcp4_tls_probe_manifest_http_len: "); + write_dec(http_len as u64); + write_ascii("\r\n"); + write_ascii("tcp4_tls_probe_manifest_body_len: "); + write_dec(body_len as u64); + write_ascii("\r\n"); + if body_len > 0 { + match parse_manifest(&http_plain[body_offset..http_len]) { + Ok(manifest) => { + write_ascii("tcp4_tls_probe_manifest_arch: "); + write_bytes(&manifest.arch[..manifest.arch_len]); + write_ascii("\r\n"); + write_ascii("tcp4_tls_probe_manifest_kernel_url: "); + write_bytes(&manifest.kernel_url[..manifest.kernel_url_len]); + write_ascii("\r\n"); + write_ascii("tcp4_tls_probe_manifest_kernel_size: "); + write_dec(manifest.kernel_size); + write_ascii("\r\n"); + write_ascii("tcp4_tls_probe_manifest_entry_point: 0x"); + write_hex64(manifest.entry_point); + write_ascii("\r\n"); + return Some(manifest); + } + Err(_) => { + write_ascii("tcp4_tls_probe_manifest_parse_wait_more\r\n"); + } + } + } else { + write_ascii("tcp4_tls_probe_manifest_wait_body\r\n"); + } + } + + loop_count += 1; + if loop_count >= 4 { + *rx_status = EFI_NOT_READY; + return None; + } + *rx_status = tcp4_receive_once( + bs, + tcp4, + &mut encrypted_rx, + &mut encrypted_rx_len, + "tcp4_tls_probe_app_more", + ); + if rx_status.is_error() { + return None; + } + } +} + +fn https_download_kernel_probe( + bs: *mut EfiBootServices, + tcp4: *mut EfiTcp4Protocol, + tls: *mut EfiTlsProtocol, + manifest: &Manifest, +) -> EfiStatus { + if manifest.kernel_size == 0 || manifest.kernel_size > MAX_KERNEL_SIZE { + return EFI_UNSUPPORTED; + } + if (manifest.kernel_load_addr as usize % EFI_PAGE_SIZE) != 0 { + return EFI_UNSUPPORTED; + } + + let kernel_path = match https_path_from_url(&manifest.kernel_url[..manifest.kernel_url_len]) { + Ok(path) => path, + Err(status) => return status, + }; + write_ascii("tcp4_tls_probe_kernel_path: "); + write_bytes(kernel_path); + write_ascii("\r\n"); + + let pages = page_count(manifest.kernel_size); + let mut target = manifest.kernel_load_addr; + let mut allocate_status = unsafe { + ((*bs).allocate_pages)(EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, pages, &mut target) + }; + write_status("tcp4_tls_probe_kernel_allocate_pages_status: ", allocate_status); + write_ascii("tcp4_tls_probe_kernel_target_addr: 0x"); + write_hex64(target); + write_ascii("\r\n"); + if allocate_status.is_error() || target != manifest.kernel_load_addr { + write_ascii("tcp4_tls_probe_kernel_staging_fallback: yes\r\n"); + target = 0; + allocate_status = unsafe { + ((*bs).allocate_pages)(EFI_ALLOCATE_ANY_PAGES, EFI_LOADER_DATA, pages, &mut target) + }; + write_status( + "tcp4_tls_probe_kernel_staging_allocate_pages_status: ", + allocate_status, + ); + write_ascii("tcp4_tls_probe_kernel_staging_addr: 0x"); + write_hex64(target); + write_ascii("\r\n"); + if allocate_status.is_error() { + return allocate_status; + } + } + + let mut http_get = [0u8; 1536]; + let http_get_len = match build_http_get_request(kernel_path, b"close", &mut http_get) { + Ok(len) => len, + Err(status) => { + unsafe { + ((*bs).free_pages)(target, pages); + } + return status; + } + }; + + let mut encrypted_rx = [0u8; TLS_RX_MAX]; + let mut encrypted_rx_len = 0usize; + let mut status = https_send_get_with_pre_receive( + bs, + tcp4, + tls, + &http_get[..http_get_len], + &mut encrypted_rx, + &mut encrypted_rx_len, + "tcp4_tls_probe_kernel", + ); + if status.is_error() { + unsafe { + ((*bs).free_pages)(target, pages); + } + return status; + } + + let mut header = [0u8; 2048]; + let mut header_len = 0usize; + let mut saw_header = false; + let mut downloaded = 0u64; + let mut checksum = 0u32; + let mut next_progress = 256u64 * 1024; + let mut loop_count = 0usize; + let mut encrypted_rx_offset = 0usize; + + while downloaded < manifest.kernel_size { + if encrypted_rx_offset >= encrypted_rx_len { + loop_count += 1; + if loop_count > 2048 { + status = EFI_NOT_READY; + break; + } + encrypted_rx_offset = 0; + status = tcp4_receive_kernel_once( + bs, + tcp4, + &mut encrypted_rx, + &mut encrypted_rx_len, + KERNEL_TRACE_RECORDS, + ); + if status.is_error() { + break; + } + } + + let available_len = encrypted_rx_len - encrypted_rx_offset; + if tls_record_declared_len(&encrypted_rx[encrypted_rx_offset..], available_len).is_none() { + match find_tls_app_record_start(&encrypted_rx[encrypted_rx_offset..], available_len) { + Some(skip_len) if skip_len > 0 => { + write_ascii("tcp4_tls_probe_kernel_resync_skip_len: "); + write_dec(skip_len as u64); + write_ascii("\r\n"); + encrypted_rx_offset += skip_len; + continue; + } + Some(_) => {} + None => { + let carry_len = if available_len > 4 { 4 } else { available_len }; + let mut i = 0usize; + while i < carry_len { + encrypted_rx[i] = + encrypted_rx[encrypted_rx_offset + available_len - carry_len + i]; + i += 1; + } + encrypted_rx_offset = 0; + encrypted_rx_len = carry_len; + if KERNEL_TRACE_RECORDS { + write_ascii("tcp4_tls_probe_kernel_resync_carry_len: "); + write_dec(carry_len as u64); + write_ascii("\r\n"); + } + let mut appended_len = 0usize; + status = tcp4_receive_kernel_once( + bs, + tcp4, + &mut encrypted_rx[encrypted_rx_len..], + &mut appended_len, + KERNEL_TRACE_RECORDS, + ); + if status.is_error() { + break; + } + encrypted_rx_len += appended_len; + continue; + } + } + } + let current_record_len = + match tls_record_declared_len(&encrypted_rx[encrypted_rx_offset..], available_len) { + Some(record_len) => record_len, + None => { + let carry_len = if available_len > 4 { 4 } else { available_len }; + let mut i = 0usize; + while i < carry_len { + encrypted_rx[i] = + encrypted_rx[encrypted_rx_offset + available_len - carry_len + i]; + i += 1; + } + encrypted_rx_offset = 0; + encrypted_rx_len = carry_len; + if KERNEL_TRACE_RECORDS { + write_ascii("tcp4_tls_probe_kernel_carry_len: "); + write_dec(carry_len as u64); + write_ascii("\r\n"); + } + if encrypted_rx_len >= encrypted_rx.len() { + status = EFI_BUFFER_TOO_SMALL; + break; + } + let mut appended_len = 0usize; + status = tcp4_receive_kernel_once( + bs, + tcp4, + &mut encrypted_rx[encrypted_rx_len..], + &mut appended_len, + KERNEL_TRACE_RECORDS, + ); + if status.is_error() { + break; + } + encrypted_rx_len += appended_len; + continue; + } + }; + if current_record_len > available_len { + let carry_len = available_len; + let mut i = 0usize; + while i < carry_len { + encrypted_rx[i] = encrypted_rx[encrypted_rx_offset + i]; + i += 1; + } + encrypted_rx_offset = 0; + encrypted_rx_len = carry_len; + if KERNEL_TRACE_RECORDS { + write_ascii("tcp4_tls_probe_kernel_carry_len: "); + write_dec(carry_len as u64); + write_ascii("\r\n"); + write_ascii("tcp4_tls_probe_kernel_record_need_len: "); + write_dec(current_record_len as u64); + write_ascii("\r\n"); + } + if encrypted_rx_len >= encrypted_rx.len() { + status = EFI_BUFFER_TOO_SMALL; + break; + } + let mut appended_len = 0usize; + status = tcp4_receive_kernel_once( + bs, + tcp4, + &mut encrypted_rx[encrypted_rx_len..], + &mut appended_len, + KERNEL_TRACE_RECORDS, + ); + if status.is_error() { + break; + } + encrypted_rx_len += appended_len; + continue; + } + if KERNEL_TRACE_RECORDS { + write_ascii("tcp4_tls_probe_kernel_record_len: "); + write_dec(current_record_len as u64); + write_ascii("\r\n"); + } + + let (decrypt_status, decrypted_len, decrypted_ptr) = tls_process_single_fragment_quiet( + tls, + &mut encrypted_rx[encrypted_rx_offset..encrypted_rx_offset + current_record_len], + current_record_len, + EFI_TLS_DECRYPT, + ); + encrypted_rx_offset += current_record_len; + status = decrypt_status; + if status.is_error() { + write_status("tcp4_tls_probe_kernel_decrypt_status: ", status); + write_ascii("tcp4_tls_probe_kernel_decrypt_record_len: "); + write_dec(current_record_len as u64); + write_ascii("\r\n"); + break; + } + + let mut offset = 0usize; + let mut data_len = decrypted_len; + if !saw_header { + let mut i = 0usize; + while i < decrypted_len && header_len < header.len() { + let b = unsafe { read_volatile((decrypted_ptr as *const u8).add(i)) }; + header[header_len] = b; + header_len += 1; + i += 1; + if let Some(body_offset) = find_http_body_offset(&header, header_len) { + write_ascii("tcp4_tls_probe_kernel_header_len: "); + write_dec(body_offset as u64); + write_ascii("\r\n"); + if !http_response_status_is_200(&header, header_len) { + status = EFI_DEVICE_ERROR; + } + saw_header = true; + offset = i; + data_len = decrypted_len - offset; + break; + } + } + if status.is_error() { + break; + } + if !saw_header && header_len >= header.len() { + status = EFI_BUFFER_TOO_SMALL; + break; + } + if !saw_header { + data_len = 0; + } + } + + if saw_header && data_len > 0 { + let remaining = (manifest.kernel_size - downloaded) as usize; + let copy_len = if data_len > remaining { remaining } else { data_len }; + let src = unsafe { (decrypted_ptr as *const u8).add(offset) }; + let dst = (target + downloaded) as *mut u8; + let mut i = 0usize; + while i < copy_len { + let b = unsafe { read_volatile(src.add(i)) }; + unsafe { + core::ptr::write_volatile(dst.add(i), b); + } + checksum = checksum.wrapping_add(b as u32); + i += 1; + } + downloaded += copy_len as u64; + if downloaded >= next_progress { + write_ascii("tcp4_tls_probe_kernel_progress: "); + write_dec(downloaded); + write_ascii("\r\n"); + next_progress += 256u64 * 1024; + } + } + + if downloaded >= manifest.kernel_size { + break; + } + } + + write_ascii("tcp4_tls_probe_kernel_downloaded_size: "); + write_dec(downloaded); + write_ascii("\r\n"); + write_ascii("tcp4_tls_probe_kernel_expected_size: "); + write_dec(manifest.kernel_size); + write_ascii("\r\n"); + write_ascii("tcp4_tls_probe_kernel_checksum32: 0x"); + write_hex64(checksum as u64); + write_ascii("\r\n"); + + if status.is_error() || downloaded != manifest.kernel_size { + unsafe { + ((*bs).free_pages)(target, pages); + } + return if status.is_error() { + status + } else { + EFI_DEVICE_ERROR + }; + } + + EFI_SUCCESS +} + fn tls_process_single_fragment( tls: *mut EfiTlsProtocol, bytes: &mut [u8], @@ -435,6 +1187,34 @@ fn tls_process_single_fragment( (status, fragment_len, fragment_buffer) } +fn tls_process_single_fragment_quiet( + tls: *mut EfiTlsProtocol, + bytes: &mut [u8], + len: usize, + process_type: u32, +) -> (EfiStatus, usize, *mut c_void) { + let mut fragment = EfiTlsFragmentData { + fragment_length: len as u32, + fragment_buffer: bytes.as_mut_ptr() as *mut c_void, + }; + let mut fragment_ptr = &mut fragment as *mut EfiTlsFragmentData; + let mut fragment_count = 1u32; + let status = unsafe { + ((*tls).process_packet)(tls, &mut fragment_ptr, &mut fragment_count, process_type) + }; + let fragment_len = if status.is_error() || fragment_ptr.is_null() { + 0 + } else { + unsafe { (*fragment_ptr).fragment_length as usize } + }; + let fragment_buffer = if status.is_error() || fragment_ptr.is_null() { + null_mut() + } else { + unsafe { (*fragment_ptr).fragment_buffer } + }; + (status, fragment_len, fragment_buffer) +} + fn copy_from_ptr(out: &mut [u8], src: *mut c_void, len: usize) -> usize { if src.is_null() { return 0; @@ -695,7 +1475,7 @@ fn tcp4_tls_clienthello_probe(bs: *mut EfiBootServices) -> EfiStatus { subnet_mask: [0; 4], station_port: 0, remote_address: [10, 3, 10, 229], - remote_port: 443, + remote_port: 3443, active_flag: 1, }, control_option: EfiTcp4Option { @@ -857,68 +1637,24 @@ fn tcp4_tls_clienthello_probe(bs: *mut EfiBootServices) -> EfiStatus { ); round += 1; } - let final_state = tls_session_state(tls, "tcp4_tls_probe_tls_final"); - if !rx_status.is_error() && final_state == EFI_TLS_SESSION_DATA_TRANSFERRING { - let http_get = b"GET /boot/boards/loongchip-httpboot-smoke/current/manifest.json HTTP/1.0\r\nHost: 10.3.10.229\r\nConnection: close\r\n\r\n"; - let mut plain_record = [0u8; 1024]; - let plain_record_len = build_tls_plaintext_record(&mut plain_record, http_get); - write_ascii("tcp4_tls_probe_app_plain_record_len: "); - write_dec(plain_record_len as u64); + if let Some(manifest) = https_get_manifest_probe(bs, tcp4, tls, &mut rx_status) { + write_ascii("tcp4_tls_probe_manifest_parse_status: ok\r\n"); + write_ascii("tcp4_tls_probe_next_kernel_size: "); + write_dec(manifest.kernel_size); write_ascii("\r\n"); - if plain_record_len == 0 { - rx_status = EFI_BUFFER_TOO_SMALL; - } else { - let (encrypt_status, encrypted_len, encrypted_ptr) = tls_process_single_fragment( - tls, - &mut plain_record, - plain_record_len, - EFI_TLS_ENCRYPT, - "tcp4_tls_probe_app_encrypt", - ); - rx_status = encrypt_status; - if !rx_status.is_error() && encrypted_len > 0 { - let mut encrypted = [0u8; 2048]; - let encrypted_len = copy_from_ptr(&mut encrypted, encrypted_ptr, encrypted_len); - let encrypted_wire_len = tls_record_total_len(&encrypted, encrypted_len); - write_ascii("tcp4_tls_probe_app_encrypt_wire_len: "); - write_dec(encrypted_wire_len as u64); - write_ascii("\r\n"); - print_tcp4_first5( - "tcp4_tls_probe_app_encrypt", - "_first5: ", - &encrypted, - encrypted_wire_len, - ); - let mut encrypted_rx = [0u8; 8192]; - let mut encrypted_rx_len = 0usize; - rx_status = tcp4_transmit_with_pre_receive( - bs, - tcp4, - &mut encrypted[..encrypted_wire_len], - &mut encrypted_rx, - &mut encrypted_rx_len, - "tcp4_tls_probe_app", - ); - if !rx_status.is_error() { - let (decrypt_status, decrypted_len, decrypted_ptr) = - tls_process_single_fragment( - tls, - &mut encrypted_rx, - encrypted_rx_len, - EFI_TLS_DECRYPT, - "tcp4_tls_probe_app_decrypt", - ); - rx_status = decrypt_status; - if !rx_status.is_error() && decrypted_len > 0 { - let mut decrypted = [0u8; 512]; - let decrypted_len = copy_from_ptr(&mut decrypted, decrypted_ptr, decrypted_len); - print_ascii_prefix( - "tcp4_tls_probe_app_decrypt", - &decrypted, - decrypted_len, - ); - } - } + rx_status = https_download_kernel_probe(bs, tcp4, tls, &manifest); + write_status("tcp4_tls_probe_kernel_download_status: ", rx_status); + if !rx_status.is_error() { + let mut map_key = 0usize; + let status = print_memory_map(bs, &mut map_key); + write_ascii("boot_jump_enabled: "); + write_ascii(if OSTOOL_ENABLE_BOOT_JUMP { + "yes\r\n" + } else { + "no\r\n" + }); + if !OSTOOL_ENABLE_BOOT_JUMP || status.is_error() { + write_ascii("jump_skipped: boot jump disabled\r\n"); } } } From 483acd5810d56ffb8fa7392a73616418303d9369 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Fri, 15 May 2026 07:15:57 +0000 Subject: [PATCH 27/39] feat: implement kernel boot jump with exit boot services and memory diagnostics for UEFI loader --- loongarch64-uefi-loader/src/abi.rs | 1 + loongarch64-uefi-loader/src/boot.rs | 154 ++++++++++++++++++++++++++ loongarch64-uefi-loader/src/flow.rs | 8 +- loongarch64-uefi-loader/src/loader.rs | 1 + loongarch64-uefi-loader/src/tcp4.rs | 83 +++++++++++--- ostool/src/run/httpboot.rs | 1 + picture/start.jpg | Bin 0 -> 683866 bytes 7 files changed, 231 insertions(+), 17 deletions(-) create mode 100644 picture/start.jpg diff --git a/loongarch64-uefi-loader/src/abi.rs b/loongarch64-uefi-loader/src/abi.rs index 133afd71..44fa8fa3 100644 --- a/loongarch64-uefi-loader/src/abi.rs +++ b/loongarch64-uefi-loader/src/abi.rs @@ -22,6 +22,7 @@ const EFI_NOT_FOUND: EfiStatus = EfiStatus(EFI_ERROR_BIT | 14); const EFI_ALLOCATE_ANY_PAGES: EfiAllocateType = 0; const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 2; const EFI_LOADER_DATA: EfiMemoryType = 2; +const EFI_CONVENTIONAL_MEMORY: EfiMemoryType = 7; const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; const EVT_NOTIFY_SIGNAL: u32 = 0x0000_0200; const TPL_CALLBACK: EfiTpl = 8; diff --git a/loongarch64-uefi-loader/src/boot.rs b/loongarch64-uefi-loader/src/boot.rs index 05570aa1..163087a3 100644 --- a/loongarch64-uefi-loader/src/boot.rs +++ b/loongarch64-uefi-loader/src/boot.rs @@ -116,6 +116,160 @@ fn print_memory_map(bs: *mut EfiBootServices, map_key_out: &mut usize) -> EfiSta write_ascii("\r\n"); status } + +fn print_memory_descriptor(label: &str, descriptor: *const EfiMemoryDescriptor) { + if descriptor.is_null() { + write_ascii(label); + write_ascii("_found: no\r\n"); + return; + } + + let desc = unsafe { &*descriptor }; + write_ascii(label); + write_ascii("_found: yes\r\n"); + write_ascii(label); + write_ascii("_type: "); + write_dec(desc.memory_type as u64); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_physical_start: 0x"); + write_hex64(desc.physical_start); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_pages: "); + write_dec(desc.number_of_pages); + write_ascii("\r\n"); + write_ascii(label); + write_ascii("_physical_end: 0x"); + write_hex64(desc.physical_start + desc.number_of_pages * EFI_PAGE_SIZE as u64); + write_ascii("\r\n"); +} + +fn memory_descriptor_contains(desc: &EfiMemoryDescriptor, address: u64) -> bool { + let start = desc.physical_start; + let end = start + desc.number_of_pages * EFI_PAGE_SIZE as u64; + start <= address && address < end +} + +fn memory_descriptor_contains_range(desc: &EfiMemoryDescriptor, target: u64, size: u64) -> bool { + if size == 0 { + return false; + } + let start = desc.physical_start; + let end = start + desc.number_of_pages * EFI_PAGE_SIZE as u64; + let target_end = target + size; + start <= target && target_end <= end +} + +fn target_range_has_memory_type( + bs: *mut EfiBootServices, + target: u64, + size: u64, + memory_type: EfiMemoryType, +) -> bool { + let mut map_size = MEMORY_MAP_MAX; + let mut map_key = 0usize; + let mut descriptor_size = 0usize; + let mut descriptor_version = 0u32; + let memory_map = core::ptr::addr_of_mut!(MEMORY_MAP) as *mut EfiMemoryDescriptor; + let status = unsafe { + ((*bs).get_memory_map)( + &mut map_size, + memory_map, + &mut map_key, + &mut descriptor_size, + &mut descriptor_version, + ) + }; + if status.is_error() || descriptor_size == 0 { + return false; + } + + let count = map_size / descriptor_size; + let mut i = 0usize; + while i < count { + let desc_ptr = unsafe { (memory_map as *const u8).add(i * descriptor_size) } + as *const EfiMemoryDescriptor; + let desc = unsafe { &*desc_ptr }; + if desc.memory_type == memory_type && memory_descriptor_contains_range(desc, target, size) + { + return true; + } + i += 1; + } + false +} + +fn print_target_memory_map_probe( + bs: *mut EfiBootServices, + target: u64, + size: u64, +) -> EfiStatus { + let mut map_size = MEMORY_MAP_MAX; + let mut map_key = 0usize; + let mut descriptor_size = 0usize; + let mut descriptor_version = 0u32; + let memory_map = core::ptr::addr_of_mut!(MEMORY_MAP) as *mut EfiMemoryDescriptor; + let status = unsafe { + ((*bs).get_memory_map)( + &mut map_size, + memory_map, + &mut map_key, + &mut descriptor_size, + &mut descriptor_version, + ) + }; + write_status("target_memory_map_status: ", status); + if status.is_error() || descriptor_size == 0 || size == 0 { + return status; + } + + let target_end = target + size; + let target_last = target_end - 1; + write_ascii("target_memory_range_start: 0x"); + write_hex64(target); + write_ascii("\r\n"); + write_ascii("target_memory_range_end: 0x"); + write_hex64(target_end); + write_ascii("\r\n"); + + let mut start_desc: *const EfiMemoryDescriptor = null_mut(); + let mut last_desc: *const EfiMemoryDescriptor = null_mut(); + let mut best_start = 0u64; + let mut best_pages = 0u64; + let count = map_size / descriptor_size; + let mut i = 0usize; + while i < count { + let desc_ptr = unsafe { (memory_map as *const u8).add(i * descriptor_size) } + as *const EfiMemoryDescriptor; + let desc = unsafe { &*desc_ptr }; + if start_desc.is_null() && memory_descriptor_contains(desc, target) { + start_desc = desc_ptr; + } + if last_desc.is_null() && memory_descriptor_contains(desc, target_last) { + last_desc = desc_ptr; + } + if desc.memory_type == EFI_CONVENTIONAL_MEMORY && desc.number_of_pages > best_pages { + best_start = desc.physical_start; + best_pages = desc.number_of_pages; + } + i += 1; + } + + print_memory_descriptor("target_start_desc", start_desc); + print_memory_descriptor("target_last_desc", last_desc); + write_ascii("memory_map_best_conventional_start: 0x"); + write_hex64(best_start); + write_ascii("\r\n"); + write_ascii("memory_map_best_conventional_pages: "); + write_dec(best_pages); + write_ascii("\r\n"); + write_ascii("memory_map_best_conventional_end: 0x"); + write_hex64(best_start + best_pages * EFI_PAGE_SIZE as u64); + write_ascii("\r\n"); + status +} + fn call_kernel(entry_point: u64) -> ! { let entry: extern "C" fn() = unsafe { core::mem::transmute(entry_point as usize) }; entry(); diff --git a/loongarch64-uefi-loader/src/flow.rs b/loongarch64-uefi-loader/src/flow.rs index d98de95b..bd21a7d2 100644 --- a/loongarch64-uefi-loader/src/flow.rs +++ b/loongarch64-uefi-loader/src/flow.rs @@ -88,6 +88,9 @@ extern "C" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTable) -> E write_ascii("manifest_url: "); write_ascii(OSTOOL_MANIFEST_URL); write_ascii("\r\n"); + write_ascii("loader_build_id: "); + write_ascii(OSTOOL_LOONGARCH64_LOADER_BUILD_ID); + write_ascii("\r\n"); write_ascii("log_mode: summary\r\n"); let bs = unsafe { @@ -113,7 +116,10 @@ extern "C" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTable) -> E configure_tls_ca(bs); run_tcp4_probe(bs); run_tls_clienthello_probe(bs); - tcp4_tls_clienthello_probe(bs); + let tcp4_tls_status = tcp4_tls_clienthello_probe(image, bs); + if !tcp4_tls_status.is_error() { + return EFI_SUCCESS; + } let mut service_count = 0usize; let mut service_handles = null_mut(); diff --git a/loongarch64-uefi-loader/src/loader.rs b/loongarch64-uefi-loader/src/loader.rs index aa49d033..874f7729 100644 --- a/loongarch64-uefi-loader/src/loader.rs +++ b/loongarch64-uefi-loader/src/loader.rs @@ -3,6 +3,7 @@ use core::ptr::{null_mut, read_volatile}; const OSTOOL_MANIFEST_URL: &str = env!("OSTOOL_MANIFEST_URL"); const OSTOOL_ENABLE_BOOT_JUMP: bool = cfg!(ostool_enable_boot_jump); +const OSTOOL_LOONGARCH64_LOADER_BUILD_ID: &str = "start43-real-boot-jump"; include!("abi.rs"); include!("console.rs"); diff --git a/loongarch64-uefi-loader/src/tcp4.rs b/loongarch64-uefi-loader/src/tcp4.rs index a70b7426..452d71ab 100644 --- a/loongarch64-uefi-loader/src/tcp4.rs +++ b/loongarch64-uefi-loader/src/tcp4.rs @@ -789,6 +789,9 @@ fn https_get_manifest_probe( write_ascii("tcp4_tls_probe_manifest_kernel_size: "); write_dec(manifest.kernel_size); write_ascii("\r\n"); + write_ascii("tcp4_tls_probe_manifest_kernel_load_addr: 0x"); + write_hex64(manifest.kernel_load_addr); + write_ascii("\r\n"); write_ascii("tcp4_tls_probe_manifest_entry_point: 0x"); write_hex64(manifest.entry_point); write_ascii("\r\n"); @@ -826,6 +829,7 @@ fn https_download_kernel_probe( tcp4: *mut EfiTcp4Protocol, tls: *mut EfiTlsProtocol, manifest: &Manifest, + loaded_at_manifest_addr: &mut bool, ) -> EfiStatus { if manifest.kernel_size == 0 || manifest.kernel_size > MAX_KERNEL_SIZE { return EFI_UNSUPPORTED; @@ -852,22 +856,52 @@ fn https_download_kernel_probe( write_hex64(target); write_ascii("\r\n"); if allocate_status.is_error() || target != manifest.kernel_load_addr { - write_ascii("tcp4_tls_probe_kernel_staging_fallback: yes\r\n"); - target = 0; - allocate_status = unsafe { - ((*bs).allocate_pages)(EFI_ALLOCATE_ANY_PAGES, EFI_LOADER_DATA, pages, &mut target) - }; - write_status( - "tcp4_tls_probe_kernel_staging_allocate_pages_status: ", - allocate_status, + let target_is_loader_data = target_range_has_memory_type( + bs, + manifest.kernel_load_addr, + manifest.kernel_size, + EFI_LOADER_DATA, ); - write_ascii("tcp4_tls_probe_kernel_staging_addr: 0x"); - write_hex64(target); - write_ascii("\r\n"); - if allocate_status.is_error() { - return allocate_status; + write_ascii("tcp4_tls_probe_kernel_target_loader_data_after_allocate: "); + write_ascii(if target_is_loader_data { + "yes\r\n" + } else { + "no\r\n" + }); + if target == manifest.kernel_load_addr && target_is_loader_data { + write_ascii("tcp4_tls_probe_kernel_allocate_error_accepted: yes\r\n"); + *loaded_at_manifest_addr = true; + } else { + *loaded_at_manifest_addr = false; + write_ascii("tcp4_tls_probe_kernel_staging_fallback: yes\r\n"); + target = 0; + allocate_status = unsafe { + ((*bs).allocate_pages)(EFI_ALLOCATE_ANY_PAGES, EFI_LOADER_DATA, pages, &mut target) + }; + write_status( + "tcp4_tls_probe_kernel_staging_allocate_pages_status: ", + allocate_status, + ); + write_ascii("tcp4_tls_probe_kernel_staging_addr: 0x"); + write_hex64(target); + write_ascii("\r\n"); + if allocate_status.is_error() { + return allocate_status; + } + *loaded_at_manifest_addr = target == manifest.kernel_load_addr; } + } else { + *loaded_at_manifest_addr = true; } + write_ascii("tcp4_tls_probe_kernel_final_load_addr: 0x"); + write_hex64(target); + write_ascii("\r\n"); + write_ascii("tcp4_tls_probe_kernel_final_load_addr_ready: "); + write_ascii(if *loaded_at_manifest_addr { + "yes\r\n" + } else { + "no\r\n" + }); let mut http_get = [0u8; 1536]; let http_get_len = match build_http_get_request(kernel_path, b"close", &mut http_get) { @@ -1325,7 +1359,7 @@ fn tcp4_transmit_with_pre_receive( rx_status } -fn tcp4_tls_clienthello_probe(bs: *mut EfiBootServices) -> EfiStatus { +fn tcp4_tls_clienthello_probe(image: EfiHandle, bs: *mut EfiBootServices) -> EfiStatus { write_ascii("tcp4_tls_probe_start\r\n"); let mut tls_service_count = 0usize; @@ -1642,7 +1676,8 @@ fn tcp4_tls_clienthello_probe(bs: *mut EfiBootServices) -> EfiStatus { write_ascii("tcp4_tls_probe_next_kernel_size: "); write_dec(manifest.kernel_size); write_ascii("\r\n"); - rx_status = https_download_kernel_probe(bs, tcp4, tls, &manifest); + let mut loaded_at_manifest_addr = false; + rx_status = https_download_kernel_probe(bs, tcp4, tls, &manifest, &mut loaded_at_manifest_addr); write_status("tcp4_tls_probe_kernel_download_status: ", rx_status); if !rx_status.is_error() { let mut map_key = 0usize; @@ -1653,8 +1688,24 @@ fn tcp4_tls_clienthello_probe(bs: *mut EfiBootServices) -> EfiStatus { } else { "no\r\n" }); - if !OSTOOL_ENABLE_BOOT_JUMP || status.is_error() { + write_ascii("boot_jump_load_address_ready: "); + write_ascii(if loaded_at_manifest_addr { + "yes\r\n" + } else { + "no\r\n" + }); + if !loaded_at_manifest_addr { + print_target_memory_map_probe(bs, manifest.kernel_load_addr, manifest.kernel_size); + write_ascii("jump_skipped: kernel is in staging buffer\r\n"); + } else if !OSTOOL_ENABLE_BOOT_JUMP || status.is_error() { write_ascii("jump_skipped: boot jump disabled\r\n"); + } else { + let exit_status = unsafe { ((*bs).exit_boot_services)(image, map_key) }; + if !exit_status.is_error() { + call_kernel(manifest.entry_point); + } + write_status("exit_boot_services_status: ", exit_status); + write_ascii("jump_failed\r\n"); } } } diff --git a/ostool/src/run/httpboot.rs b/ostool/src/run/httpboot.rs index a8197c75..b46bc12d 100644 --- a/ostool/src/run/httpboot.rs +++ b/ostool/src/run/httpboot.rs @@ -412,6 +412,7 @@ fn uefi_boot_arch_name(arch: &UefiBootArch) -> &'static str { UefiBootArch::Riscv64 => "riscv64", UefiBootArch::Other => "other", } + } fn normalize_required_string( diff --git a/picture/start.jpg b/picture/start.jpg new file mode 100644 index 0000000000000000000000000000000000000000..73a071ad2bbcafcea3d1b5c45b773d2a86242825 GIT binary patch literal 683866 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 =?+V%;;28#r>OdWem4+q-zW#$R*U1!`vSpT`c1 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%0DXq9WvJ(F8ZJA1IY5%Xq za`@CqCQAgp-8wQ|u0O2F=VQAZ_N)D0yo1TlBMEB(#}mf+9?lSv7RhT80us+?-_8xd z=T;L4%*=s#G0uetYKuA%c|b#uxFq($Ch1MkduGG z#hxp}jV|KZ(rV78Xo!dVW1?NM$I>p?l`eso<7#!~(viG7mfeI2#nCGI*E2KUhS7Vz ze#_yF)inG7Evr6%HyZ(hOdaV+IatrFU7=5)n2vW~qT(^z+2y1RC| zt*2#%gU%Es`Ku2n40EX$%Xio85_4-Kod&!JvgJC(8rj^*>IHX?>X_?Ov~+mBbxEiS zOR$q{`;;!oLURub@6{h<-J~cJF{heq@X_{Pq;d!FNyA^f(>=}K{wB(yM_5^?guD5U zL}!1qfUeQtboxv!7DTuYg&K}lCHfQ!$;W9$c0Bdgxu?4C(oVzuz3R2Coq~Accat*> z8P>hmwzo$j?&X__O;Xd~b@e#6JJ+WHJ91KA;b|=Nh}7VMZeYlmk&iy_2H|uF@?{=; z(F*zlK+W2v@4tZ|sVN<)sZrD25+!3n;|lBg6Pmap=yAt3k&Jz&?M;0OWLJdF z&vl~9U;_EX%#&#}&246z4s(7x_adluu*WYZi^cQ!NmOTu@fGA2!}O~u}SEtK|b zhGZ~k;salHH=|N#GDR7@Iq(K$w0-VifHy2s7XC-Nrs0KZOd>oG>|4`@6;El0y2jSR zmeiy4;uXvDmr@rBEb?>tW2Wtur1}j5Cs*IsbI&kAOzKsS3O>}U-rix+=-gHOj?oH| zVRlI*T$z2@ozL=hG4}UZ;7vmQ`NwtB{kLUt;c(8DZaWUXyibuSP27~Rg#ozViH@hb z0(Q?eYBYqDr<-uS+5&vIROqM~?z}L(xvkqZ(V}*)A45zIZ+`I+nyo^AuyHVGANd!r zAWECCud~OT$vMd5Ga#50O-{7@>^Vd+yqg||O>6o5-&%SQvK4l=hARqkBDm|gN1oje zs_axo)8lr9Noiev^3FUE60%)oCUoo_q%ZW5FSjn`v^sY`Z!kmW2(AK$GHpy%+s$`h zu@j%S68ef&T%a(>aW}l!f?S*HQ-=n~o;HcJtAX9Uyn<#9e^r z($()?s7`&u)i>cjR6fs}{45V|_!+Y-8{6_|<@+C<(9j6?P;(>H(-dz9OX{quD*+i^ z<2)_Jf$p6+Q574TvM(i96nhw*uQt4OFYn4dE}(g#a<7aC`XoA5GRa&!`K5GCL@8F3 zb+c_GXokG($6q{)IO9;Ru8AjbA;`gi3`)hkrq;u4LMVM;=0O?h#JH$Mv|~@7V1%qh zUd^Jgo#^_2*wZPsmzczGpP?9Cm7PmBAXyZ(guPkskmM!>I)%Yd>% z)#oYvF*#9jtt97Q|FWB~CE#h6G6YFn9uW0i`TC_q?Mja>HX3V}fn@P?Q2%yT!mN4L zA_GDVjvm%pZ%5hPbBq)G&f<;PU-qjCI}|SoX7t^_2jQHC@ym5^f$1mBSNxK+CfL9%h&MyNrVDMSti4tP@*yRYRH) z(f;$>)iNwffFkuo8IPv5w$>*nV0on>qUm%%24<^hBKP?xv$V@NR=&hB7B~;g#hfq3 zB(ApiUk_rJdS|tYk%7&ap~)7Y8v#F|sHKFKaB(chTa1?u8SCjnHRR&yhzZ&C*XlCN zB#T!sv+X$LuLK!s+Tc|oGNQ?TvCMtDmE;1i#f zWW#`i9B7PvOSR)C_dQzUdFLEf93cUzQhw3Xs3q&UD^YxNH?PADx*HKbh|WYuBTvqr;Gk2Zjsb;_V5jj_4Nk;_rle3Z(Wk| zg(hog*^QK&-K#e*rEEYr6_JZ<9hNxjaskP4kbAc-im4i;@E#K+%+yF# zI~V-LyZJe{(zG@vL9QxP|FBLi^_SH3)JYbU+STn_ijv3t!|jK{2Fj$rCuB>r`>&?D zrM&~N@oK(9F=q)^GV`la43}8%!%o5>ZM~JJ8|~wbxrg78@RJa9uj89nfQ z$a+U10_YwE<)>6ZJNHKpN7i7RTQ1ZBkBAH#Mm{^uXnpHi>ox8l7MjaP)`9T-6HGyM zu6dlA$e{;rSK+$nU%a@kkLRN!w$p17_1tr;VGZRFY*fMA=Jj3TkS4AUlK~m{hKkLj zSJ`-y4nIfN@U^gP(n3To*#64*Gb3+!H^|FFDurZfPXO2jD%6JOBo3;@e|)EQA|bse zp;~Nhy?tMHjCSQoR2}t6fXp*&8I25+Nh^C<7r@;G2y!t*Nyb6nq+)s{X_{bjvZ0^$T`#;7RYcl zMj)pC_I&3PDL>L)jW+eb7JY5;Dytc9Zr0UqT+9alR)BFoIf>aXbX~DE*HVyiKL>Hz zYnSk2M~zvN=^{V-m!DVcUC}M#W|T#lDB|gul^S&ws_Z;dW^VQ9x;!WCYBab67U9Wk zZ!3F1c2mS|O)9ST2WAW2=5mvB`!C)`a%<gS?o^xbM`A(m5BUjFwtqHaI zPz;N#ke_EUv1EG*tgKEwHUcwwUOs$hUQva&eRt*a+aICvFI7)HNUw5j_p zU4~7w`YceenUn2GxOiGmvEI}iNrL%e7a#dkfwp9fNms70JD5-zULp@Q2FU@m-yHLD zj=zf0zBT+Bzr)$FV)Lj2TK|LFyMrOJMRcK>19C$c@GA zJuSr^KLor&cD_;Nc+H*S1H=O{r+KWcordvmEi>n7<7?XpejmA4zYR;ljl^aB4(i)* z^)X+~ivVAy8p!!=8uhb4v%2&A_xI)su_LLcKEn%%yCrsh$N@2KzJ9kSe|~M8#$Si; z1Eq|7Vzks~!@OaX3+~tjbsFq5F6Z{pmrpamYnHx)1aphBpIqzc=1mPo2TXyenhky< zx)2#gl}cKs4y;fe3PrusE)F7Je;yP>pOrXk*c9nF&Ci5^E2PUZXIx%1YXv?DiSk#~ zAzQcnt&*#OFU4tSz?`lVcA}&HV73)^wLwSRVDtw(3BPrIgQbbgJR`62 zjzs5j3KNVgWJ_z~=9B4s8Nu$aHE&{n?>7EP0uqD{s3+DAHmPU>Jsut##2z*4aOBT{ zX-oY~7RSH`$W-ihD4?S5`YCplRVPdj-_6edhD%&J2ua;iDxl#hfg+pG9aTjn-*Rr2 z9o~7mRk=+S3zui+ z4r!VV_`KS~?%$GciKAKPUJO>PA?>J}Bl_U`1D?#;oL#6qZx<&q&&~t6AUV_V;@_~~ z?PaXlFLNA-PsrJ20#;{2G1cLSULBsVj^s`=dDLGn9v4mp{0`C$B#Cr#2}cQnu$d=u zvvg&Bfr5nl+E8TqF`4A7=!GEkiDtMuZ#4)SzEns5PqU_TgqEp``DV6~BV>lnY1b+? zzJbHJ;_h32UM_)W6EIaZ1onSYX|mQLa4b)7HAu2;6653XqXA zC=KO;X48g#&G|4M(Da!UzTRH!^L0@_^L)gkyLoVSHl?M4zqXfupfLro8fc=UWs9ceXzE-;-gllD1sg18?}~FW6ipufp&b(SaxKD$E#0{ z^?NFvSTse+Esd%+ZpVN~r~UzUV@cuF2J=|GlJ*V=gzqWEj%H$=+$j^|xwh6h9JR%WDu`I%3di~&h{b0xem`y(@%tYX8glZmNB-s>TWs8_N;NIYFJ;@jABuS;TR&f zHq@87S2T@PPd>{{wVuAFJKnX4$hR>;y^9nPzTBEA-xUAqcgR}0(VgXKuDomHh7~S; z3|kELmM`-5|1@ZH=cozD5k}tbxHG1@i;w*1%P6UvX>4lK&_3%iA`HiQIks7p-qwUt#$7JyGZOE9S12AC<@o2fi{sH7@F;_tWmj6F5|$5-8+sY=ANr`XaA} zSe?N;5}%M}@)ls~9+D64gIReoj{r&$n=4S{Bh+4t5{3lh>t`iT`>s<>89aULEcNL) zJNpH1b-Tq(Z)ED}dtB99JNiVN#a1Ww=o$f=h?q@ToMWSghT6llQRI;Lq=nAZ9bOR} z8GH~~B$+a8f=VL7%RJ3z-P)*?5oWT#FPPld%(*j~LJ6&Ddv`QAV| zA@Wh=Xn6r9ZP{Zn@e!|xg0O`!KVIKReqHwU@3)@ugQ!AbF`M_>#{C)zVbAKU@zXz! zR^7JtJJdS6ggtF=I}~^`8m}*_d59@M-rZGZmd6uW0CWU$Z<|M9Y`-$E`+vPu!M;`p z`35}70KonZg4T1QU$*o6OA%j>3kA#9OU6ObCRalP6t#|k9w!h5uoy7}j=>4iv;k19 z@IR^XwadVc{{t2Rkp2=5|GzNT%SelV51t$*|I^v#6LhBsM0t8S26VOfChL) z@G$8F+e$K5qYF^n(z5;>v(+VroiC!#oJDD%If2?l!lRh+R&fTJ84WihL?3e}{P@{H@vlqBWN!B1aXrE5& z+r4l1iqU7u_l56xYZ$^y!?6p-{j*sfNYlsTbacRg>>Zo0`aCRHz9E5I@aiFBr@DG? z&fJUagnLURBE>PIOhXe>mA9bv3N;rxaj}IZnX3$PK~jDjzO4`=Z9O@%$LrY%mG7Pr zwH8XwHVNP6(XgR$oYu$rCK4XzdlTEL-P65|h-2Z{WE1p&9-_FhXxrT;4>Qy2s|O3O zX6<;nDfGqDsbS=-g{+W)ywCVKEp+b%NOHg8{QPhy%R8un~yFNZNIJGcKT^59&T zZNC~Clzf|;FD5*$!`hqp_Qbr80}Ds?Z?hU1w}uxAax?m=FqCto?$o%leL-=ZiA{&K zlrt-T?1YI;fyes@pwyyL$LLj5IUC-SH5U|0N6z=7{#oo(KbP&Bq&3 z^!EcRu$h1H>=Q4vOUZ1<1$n2kE7%U7ueo}m!OnrEbfNSN3q9^`%9dNYCg~gO1IAVP z@4FVB7==96IkXrcSd;t$lW;5uCk-VZ=`6T&_@O|c3XAm>dz6Q7;bECD-5tBC;q8ZL zagSRAD^&F0pb~|_HE1AxT#b&-`c>rvR2cpc?{E9W)0`vfQPHe=;@&1@MbIt#?nDj-e|{?3ewESGoB@K$(}5!L;`$)3l+FyS4rx4vONyx2r1Ti zifPhdpWK;^kuNaaydL3YK^`?-xy5GjY2%*O&nNVSiQuLVmOU}IL4P?&_sHM!t8(U!CvS;aPT|L4DBLOk z$d8l^Fu5^&mEj_$;>U~8_%jSL=mGl&a(VxoNt|*WM@wqW~AhnWwQ7?jyV0^EbSc55Uz|9Ta3nU-sO9{@pFJK?r<5ms8=@f1Kl{!@n1~?M5*L;#u98DW>q;s6nu+|E&a&dIo0u-<9ftJTCu=4Ja<(0hsgu%l!n& zMKXAl5?MjfovUw)njyxy#k!yh?@k=pOUJMDUn#8kNFEk6&;5$y`sP9j?3I=F?X#{| zNzUpGVLkVK9A15_Sy9e)1~v?eKrS1gjQ{)>Z%i4GLkMgvL{WLf8pO`#ThzwcdxfED z(rkFyX#hL5`Y}j|9$|gO#m5PmGnQ?3hbQnCG+7sTSguwdDmbz$k#E2D6v%Ny7iYeG zc1%rpBoMBYAV^?>BfAxc{{6xiq2n;tJ3G@b%pUmAsZlu3I=ve2nvLER-yof431ehK zx$54^TaqRHj2hw{gbmbJW~ze+yVEm4IFilT9H%cEh1PCpkJSFD8nbH@-c!cKOxDZD zzO7>_{lI-S%I+&m$ElSzQwaJ{ZA|dWNCakd%4616%C-{-wak<%9UDobAv+xSsz}sg z?bmxOroCJW5+X+0!M9=^?pvbbUz8o-@j*I zn+OJPT-na)ala$ey;B6&hdi4gzSP~N4{0Sm)8-(e*z6G3*Funz1`q~Y@(8cHjNo|+;Eq#^?i-B>NoJ9DBnjA-Vk8<%> z%8JPGq!E>yLVea-+tA7ZWY4)mII>(Jx0j>mSC;*PJ5HOPc!n@D=5;TIRUGYNcuMxH z!2JBXd5p*{>`0X=tZiIOb829yw;sA^+;D^jVm8G`+t+t;Vvq-|JZ1;wf@1KZU#msE z>;_NRr{OMl@!<6><;%zt>QflHxKmn;&h?m5_Ts!`MsVhJ%~rqgq!AU`MuXFSM$B(} zRy-c4Ey1+Zl)veCqkOc9%ciYNXBKd*uhFoX(b@mxvZDuj4ULm3oQ76pJmIK zF8Cyr=tjo*^1S-oEpd$KH1TRemV+)7&NcM2+qLp#`tMTlws$MBE?v*TT`rYb?qY$L=Vz*#X4tg zr-4VdUvvOae1m<|>wQHxaN3Wjp7Uw2OnGqJ_TJx-i+VS4@)yqsBjfrz(W1VVxBkHB za1c|;I)ARII+-GpxGXI89@W<8GL1}Slej&m_VZq{#G_#7DYlRlhXyxATg*7D%*X(K zN7?hi@IA_;XZF>*YY7kD&-ORnNyCi<#CxL%apwY*qx}v}G=k_B@*P|jQG@Z5DO!Y^ z+D~&i+{LH0#y3XFmadj2^#vrDYf`wFxcB{>k8HSD!&p}g2)pQf=bykCw5rtZ>oqwv z9qhr6C_(yzsB!_B`o%c*`?|P?FKg(V8E20keo6I``RC ze@v(;q|x~0kLe?Npq}l3iUhcT>Plo=;g{>HCE+R>7tEbl-ny7n^Z~r1u8s8=6iYh1e!1rFuzT-Hk8xkqr{S#co($*xK!#xM~1cyNgpS54Z*k11?9Q`OMD6#9}^q$#w)u1E+^$^mWjbJY5xCr#Lhsb%PT2|IlIHSB z5l)0BOe9#eJY1hoj|`HyU%XWWBB5DLaX$>hG2TB+Ky|jknQU8Hf+G71QE^yt$FIH2 zKy)|dFU)f1QIYUref12yoyV!^sKo?nnM?AO`1`Q$(s53-;=Cu;rcyG4g65`}&0{&o zVvqqcEJVzUH9YHE1E1|-iKlNH&{)BbXx6tSjYVZ~7e)|_+clS3F~T7tM{|+u)*!p( zMYxoQA7x$kM=~H4ZQ&BdGQ=RCcupG=hmB;u{EK(kvuJiMHNPZpy_P(fV(9LfRch5;n2N^I5Ftk5pWcBEmeGF}>eo~oJ_hPEIw%~y$gx@FsDbISL&{Hal ziTPO_Uo zsMjEPs$L)PWNYQz#<8h=;MKd$roVV;;?u zQ}?93>1!Cgm~D415}bW&d-?UM^qQBIaMU^DL1@1VNP@Ut$(Id02kaz0jCyzOv>xRg zeMxQWZ0E@6D*TJb$;gx1UYHR?Rq{mgcMTbTR2?Iv{V8O)?rf-GfzqW}Tvsz!rhL8| z$N4b~)3=%mmn$_C* zNL-Yud0FUyWMI7*xc^i{jrkpPlb+XO%8Ff_Q-97yMjHoax>iRUK`Y#rGCH8eY)zh! z7PF0^P8(96%5~=NR*bvndRP_BrbZ!`^jCZgj_~-HrK7B-2DHrb7Wva~7yKmbd<4RCQ&EU6S*_qpKj1}TATq%B+xTyv%$u2HWL|X5GX}! z@X0AjZ@JFT)VQ4IQ`lXFThG9M+Tv1SNN1ySw5~T*(;u1lMU4ur^D{zN0Y@xRlK0n5 zt$zt3Sl)J&M|pY3-AqXgfK99N2g%w@KWIn3Yo~)(P*Gzx=iXn@@7U=?B|<+WteLaA z39qv{Wvezker$$riTFLX@g+2CQtS|2W#p@;kuhDTt1YEKeeLc8uOpWHjumkpaM8Ch zs$!`)i0LxlHMn5J;p}$uAJ4+Vgm+%?y9dLGoZim2kmS*Cy4^fc5M&Q6Qn&@~y?|98 zFVX68-!W0Xy&TqxtmhP&tn9w!uwntOS%1ZK>i+OVh~jj$T0O=5j$sd6ut>fMDR-uG zWPkrzXrq1Ec@=l%brP|>b`I>}amIT={Ri?bc4D` zQ*}EnV$x+{Gf#g-5*Kriyj!2J?Eosu#(^RG|@6TrV7kz(1NohS!^ zK3gL8+0cp^5sTx8@CJnHaY1ZjcFr`_%CQx+3$7^i_`YM5oK2J%Vhpzu8Bl#N%zdUU?-<%EN6U>8YNM?Gi`T21x}s|8!Db}2x8%L_ z@c3jgt>k^@gY>Ip6&BSGkD+{4=Q;#S&KJM!2!<2^Ui&ZVZ^7W=p`?xDg+1YNF-{=d z(7=qc!o%cGoy)nLLP%Ex26ddJEavdaFWJVtA{$? zk|xxQ%Y#ekwu?N7uZ9%6suhtdZg!QMuc4x#$frjqMI1S^ZhY`+_{+z)o6^mE+f?SX zI{##WmC`^o%8xQT<4Oer?)~OMc1*)iUps8M<97;N^e%6SZU0Bg23g!T>v7~`nWR3n zpcU~4xoZ4kbt}q-8@;D75voWTaNo2h{g$74gbu&hz)`-;u5&o(n%|)bjEFStg8lr6 zU4%0W2rM}sKqo#h10>W1YdtI_v|ozlivgonX{HDPug?R%lXT+Pc8U*i{&y}n+in!U zV{?h{p1?eUVx_yC6Mt!lDHvYlBQ4=0emPU z_6B$b6@yy;*j|TYRtYal=x_mjOp;aaJ>IC&QmOk-km zg>N23V{@%QIuwf(zms&FmdPGy(RqITd&gqY#G73!S)4GHpZzr*9D7PLr0O0Z_~mdf z43w{d9dLO3eOv-5rho$7ibd_`qnefuR4>+5bg7rNQU~(ClDCT-I^eWvsqs2bwT)8O zG&YGFm*6Pb&*x)GY6hM-qXqpYwtcLvPvA@$z!nOi`@iMwOEJ)|*)I-rZiw`TsWyDi z8tjLlpF_{~D1DTkeV;w+0rw_Ga@jwhO@wyEbHL3!1Q04)#Ojn1GrdnTd+m?GGV^O5 zKF;-qq7>8zfs0oHI+Bq9g}cOSHCe>+q*j{lXw4E-tmBE#|bN-JH+oawe|U+wS;Kj<+&Gx$C!r|Cs>r2)&@E*$T9(e zMd3TGnq}X-f{@qTs;4%@v223}IU?+%TTX-Q4r`~uBiIG0dzsa7kJYEcw0*&Om$f~L zszj2`z|fn}BL?k~T_G95{BzIH*X_vmPr_?P3bI6?T z10tFVEg|yCzL1{GTVYUg^*^xm=8RMPfX%V0XrmXv(-Ql$0eCgy6d(yGu8~i|#La62 zBXc?R2={NNssXai(`Tg9QxX0Af4cAa9r9qNAH)WGySTBUFJ~#5xQkLur`J`{ z8d|yyGm>-LhKHs$WxTi5R74YO@X|v;MFvn^CI(v0N|7+>#KwNn;(J*<{%M`PG04)3 zmU@yL0#{XR%r`FQXf7P3OF80{Re1EG?%Zhkh{|zj)X|Z=Z5QzFPd8eQ?cIxX@xNEk z)Bts!cU2|&dtYQngHwKur6>oPP2*L|Uh)?!`ab*0g%|Np_A#|BSkW=N7y2-wrdhpS zALr*o@+rgZt0n>`S-v%Huvo`!b?lghWL-$~hKB8Z8?tl7?p4=LfzXq$W2Z&K;Q$s3 zeH474mlpiCzNt&T(?qd9g3|2ZwAe?f%D0fIV68-Gc`s`%fKpdeM(!5PlI_Ry5rePm zYK4N;nnpWpP>-a0{L{29E>4;S8OuvSleKXYlH;ZhPnw({?%A~zFTeLp>$?o94}ZV# zVZT3puq1NGrv{AG$|ZjClIoqi-N&cJUuIcU5}it}gs?(9nA8YGH+A9-?(g52VGl%S zifj!ENGA@-!({Y>dTdPRSA<{jr24V%CgwVtCuj}@;#pxh^yEtqGOez`U)fNaeXsr0 zvO&NguB52{^YC^;flawujK+ux0XYb$4ztF~;s?U+7>(6Z8y)poL_?FSV6)It z#s?pt;j5Yl(0(rNr0QI*{#3V@ z^NOsN12uES{5l)yb+&exU_@DIzd+s6S*n8&n%QKxvF<`O8k0x;HArz*l!HBP=HpCv z=Rpx-LT66%evf-tVOK^A`)}0`)Vr&bj^qk8D2LNxo=hXaB~ioa;Gy{WvHg^JQ_8LE zzm-PBS!`)TC9O4m7y|})Jt=H?Lz%_%bA}%N!$mJ+I)d1rk*o2FvR?wY^`pbtKz2|4 zU(CjbQ3Pm($!=!>1Oh;~IxT?)`0jt&cK~`_0$<<(5=Z_owfsLFJ76+_=>+5@v-JZ= z{!+9L{DuEVyEdTObiY(qd!T10nW=0LG8u2s} z<4T-`7r*U3EzIBR7K44m&Tq+QinY-MjF>3cmVOyIBUJ3Xqg_}$T1kPZ7a~0*<=}Q0U%64SY9F0~J-vvuXzs^f{!b=**F$fMtGBQ?JTL0imR{9H%nvO(r_Ddt-Fp z{>@6&+Ypb(#%sCsWk%zX_fPL35Qu(=dT>vakH=Bpd){#ouCJa&ID;p_DMSZs1YCC` z>P0g!MIGp6z-~!ycC7wCEPZ8Mli&Y0phK)ONclpNiubPc3qz-Xj97vKBv``-_Ez-uqYcJ10Z=kv}9Pc@3C zBI`xrT86hY0VVGrc#Z06K9N_W#2@`+je`oq#)NPQ&Yfaz=fn5`wnt$bk{3mObkNO= zGeldSz1?i5w~=%iNo95J%E0fuU8$?d z9m`ofFLxXcm8OM z@PZX|-&G|$l!*Ir9;k-{h&jI$wIeGRyW_O+v5A}RS=}AF$F4mGL*HOx%dS!aL7w>v zHSU-2Ijl?ay8Aqbz<+qp^?#lQm+#)rB9%cMwW%F#Q4tvUf z*S2iN`LzYDkPL+{at!xn$PK~@o>*VLdT|MhGIaWBNxCEdxsZY9ydGsjzpqubnVsc(1^}7oQ>-R+}#I1+HgtCePJkH`B%uCUW<8J?F z?YUmSLdQm>YsPK1@{AWZ^3=a^iOdg=)@6@Q^#*OSX|xF60L@DAbp#7pWM`f+0=FZ3 z>UH77%#I>Wm6${9>E@hO!*kK+MPm?ZjitF?-s`|rsnqyv_O8G&-5pi7Rrt( z$OW{{-_EaKU8cQ`bmA6&U&y^=n_`EnDf=a5*7&LHv07ZV;?bV@rUHpd+peZqLh0g6 z$9e6b*LJy}?DL0&a}L+C_TSOriN&{+NHHsvi?e zP}6hz4aZCF#*3nxmlJkiTlkmPYB&-l-;f}~^;#mz5O1K1s>sbKW1nX#)z4jSYe88T z$u@jJCSZ31gky|!juv0qr-j8yk!z079-EpSEhLCmr}>?{k!)cnxT6%SkOrOPB7@5V zUPdb4kz0y1znkdr^jCtwh19Wz(PZ2WC)3U7mM@JVCagzC_uZDu@#in~EEZwb%#|nM z0T(XD+NK|TIcJsFO>KO+*+|803u$LLkSap{z+Lr!`R`!sle(+Ry}Phlr2A!93%8Dgv9B}YUw`k1lwD5`!)Ukzn}l__n`*FJuv=& zzJvcc#5BWo(7Vr-?VW45xZ1Ua)ZY3Q82YCG0*QcR1aMN?Ary_6;^c7M^Wa#HWQ8Zj zhxHx;Ddm&D$Th2flve4C?n(~sg{)O_Jc@F1xzc03ZArST+J1)v6fLxa+vnP+_dkLQ z@BhvPz^VkQwKc)+4?J>-p&xD*;0J}e5P|G6@HTH=_hVm^V4ACd-~zwJ<7t9et#>cQ zId^rPs{291xxn>BPzJmH|7bX((3>3pXR8xWtL~46ButHKn}JaNRQZ8M&`GYG3|@fZ z)_D9iBbF=!i2FFjxL0`uUntmO6BBvq+Upo1+3~A27x%cZV}Q{cDIaI8);l`$-9-sQ zJEGQfYntrc0uZ%2cPjCOKpLX0zkW`O@{_^HK)O~fu*WhjYN>X3M{D^*^Mt}j2}}j+ zoX&S&{RGhUJg;qTMD?KhqrSD4e+az47n!#odeL)-qc~Rx>lp8RA5n~xx^vqYR%zGi zsrjTL&}fab19t@mDLql}xd7jvs}zwp_J!Vap4IwVg@zD(edPulke^-K~-t#!cy(tS^b zNxGl@hoaT9xjj)37V<3; z7JK#TO5ZIhTatgjIkKd;7j6&ZUS>CJGOR-ln*|@ZE!hnm<*LyFCY~3xA4lk5$H~<5 zam_rr<^tj)JL()h^@q@TLoGS^ ze>d4|TV4m^=!NOoa|wgzp?k@DG?q;f5g3sb?2qk0CR{>;y$iq5(2?)BLGA_`=^}j* z6goR|7ru~xkRMNsMN_4^7#eQxPn4$lw4%@(1XUa@H%!Lx?9s5Rt&FSt#f_DM?fOcg zJ?^a{=dqRWb>3mdV$3}T&?>-0o|Vk1c$TOuEA53YGHPMnedL{b7?SW6XjlmM5sHit z96e^cJYsecZXWiwXKwQPQN6(|Wdro-D8rYi-pD9qLhDXuXhzD*5vh){&NK_xyQyw$8MpJ+g+|ly(aU>eST_a zq{`hThALqJzPJAb&`L?)U3V&LVTK!L31;x&K{eb#X27a#ar}W#+ ziRi$&&v9JgpL;f9zN}2&QGUg^3^P5*m&-?}op1ZPDa`vR{@^QL%-ny>q*k6AtPp8H zo|CkG^V61})k~aoL}y?#y@#B>$2{YcWVGqO?X+@#*I5dL=!@C6Iz<#5=CKu}=XxauDx zdEy=B7H474Ep7o$2c_g69yrLZcl8C@zT#E182=OnWm?^++7So*a!)?+OQ8cxugxC8hq zc-w@y&JKV*-I3vqTXQi|fGsD~z>M4=DR;Vi_T?vQ;C--L$fvqUyq<|bXf?|t?8<2# zv9k7&-y~a`@1T^{c z@GWEXE{y#zTr|e!63tKxqL|Hii5tOp7RK^8mJYVhqm=*@{zT^&rHrYr^|v7PL}zC!ZV;#7!IFi(67D_BhB%-46V(7&E+;BMH9t-^A9+jb$?Ta!VNZLG0n_R&!GK3q-4 z2l?5%J^`4*$5qlDYgMt1sG~_^*l+XqTJs?L^@?qdmIf~}{cHA^Qf=G^_<4Y8$0f{g zAZ|SYIllglWL7L$NUv=0_vcht2}`N(P0f}Tulw?J?Wuc&vohNJQ`@rmKK@S%!TgVB zFlPKKJG`xfqz%ojQVi>rgPjNCzH&0)qtBi9+EJh~Lr{p!M;ulcH4u7VIZOL`puZs& zy#Xq|{KG;GMRNu4Y9yN5X?XVT!RB?Llf@w6Gl>0WRt;BftxJCoNiQL|nG>OtnMrDa zizx$~Ld6?}(5=HO3T@noP>)VRj6NjV4V`6Y^xpGhRgt)3qOevI3NNGGKY0dX-eh`~ z2faA8Fcm>-XY7LpR=bJ8T@tPAy1|_lfEbkgWPR3!+!tlVy&SV^_kc7N!`vv0bc1&e zS%fi1GTS5iQ({Msp=uzbT-e+(oNUay00`wBHO{^SmYM0sWLt98p{ij@%9myimnuhl zEKJaEWSa(=yPCxq?Pb+vgf?MF@vLF+@oi3c*~`^m5;*?Fz%b@#%~HQLTJbawCZCz>vO z$5oOY6w?P|{FF}-cME22=9(${*IQf1Lq%`e(`r0mHEpVq$Gue19K)LzL5?g!CPSP9 zUeT|dXFMjZoo~oyc^!j%{q7!-fy)FhY+^NI>fo26Lzop4RTw)SxY&=9b6MR?6Q*6R zk4GAY9|jo9SWR>S7LR8%U~oL^n7Si`+B=@;FvOb}sinPfk%0uwUxI@bF>-JRqsPoj(xjP^0 z4q+dnp<24?wD9&_9BtbPh0a=#TnN&f46qjeSSRz2xE@*JScWk-RWxr{ny=>(u0u4G zUg=&YG1!WL40vV%=7&yc_vYK?p$8nq7dremzM3Lv zT1O!x^Y@b9^*i6qcDB5Pb!T-MG&X7aGwUK_(t3$yyVUs-ox3CO5~F>WPV}t#~e}IFMKZ;cphc6>@(e`dfC1 zZ>*fjK=omUl3JBQ5#3Kw0Dc=F@ML7)aL=c#=|Ght#&aB2)ASjF1p)P+DYHI-w9BGo9LzMCuXGfnZdtFpd(*=pO{>9Bw) zB*dU~y2e=a+q?n1?y@6(^BuqL`?Guvfb?gE z!rwW@>iM+f+c4lqv23gN?(CT~Sc?kuKg>3yc5=2%)U#Q0Gd>_Dj7)GQs3+U;f)TTK*c7=HV%!Q@Ad8Q%H$I0E`PSs^hOLAKd}@)U^NJ+lPH$ zGRg7kR#Su9@0qaOLfR*~HXH)Z-9M_mX!Gxzl)V``DrU#XPusu$6u5^4);GJ-^#`l- z@A|9QF)+~Ql*KQ3b&#jGyub+#EBM*XkFTN}7(5XTJvboI(&s)e#KzDkQ{EgLE8?o; z%NJpBzLDPIqQkTPU{0J%XhEzmIf(10<9Lzd>PEWSeAlaF1@q<^SdfAIs8UN_(cD|H zVe|y~#)Hot`}kOU$!a%uHiQ1NX|VjT-4Ybku1{c*l_mQ^tjakY^c&@dj`us2e+g+y z)uyi^1awK~1RO6g(gk}7i}(7~S;L94qfrsHthadk$J;NvsHgBPixXNa!|D%Z9Xm2| zZ3mhs&Ap07(g(j!gx2iqi5ud_L_XTMoZztZGFXsX=v<9c`()sEw4BZ2h-d%Fj|u0q zBah?^NN;mX-H<$~+=@jG)QULv2keo}_ZXVqqt@Sp&L#}kk;AQxeV4)EU?q=yi$kcy z#KdIpX(Y$9-R^Zl@wwA?WOg%&3k&N^VHG|g3c-Ub=Efdr6NBojeIvuWbJTIJ1I$^n zc&mW}1h&RLKhHHT`TJb#=WE!4 zBghSG&wzQiN#^AL(o|zF@4bxn-;BgBXqJ@LS3-3(>Yn51|D=cyPYFC08fhXON_*)~ zE$(6c8^W4~D^@O;d40(8ik{0H+9d7imoVJLBEz0wQ1`g^p%quo=w5D>Dt74(}||)sBiz;Y&vY?kq&zZ=_b{Q$l}=lTsLOk{kVDsV>nc0ca^^n{FFEaa8Ms zQrk98&G>}1D``;lWXZ#;dE)%fLw!d%--^#7IvDRmrzVG;PMCb!l&b^efENZ=aN}xQ z1ZJP#-Ox0{ad(f9uZCg|`P3GeE=uBx-a?vdL6*a!`pNwy-B=^ZK0VSezTOjtGnIAp z5#N%gcq-z{AK%A6ntc7mDU;}$$KVE1S$yTL$Ktv*4nV8T##3iXd8BRebYVVWC92#1 zCz6y0>>+b@s3^lK)0p#Y|88~jlV33V&B6ch#8?WMGC#r+Zjn65v#rTB0K^(#MkeKUpT>a9KL4to+SNQ)hQeS!rU#c) zyKSz!D!3`5mR@fHt-5F?$*fY#^Awjmdx>nD<8DP3>W|rT3*QGBg;#5c?{3K}5%Gn_ zBbC~`TvT2pWXiDTi5l8GF2J|R%liYapK`$eGKK;G@S||^f0;&v*X9qI0^sg2RiGPyRw_hde{I3vRR=NcD!KS0q12;6?Z7=j^)Vh0d0pHdy>KsznGp{`je-*jnjJE2Iq25aIFLB6^83j(8j1gK7w7rGwr;FQTYAH)#_g%)c&5n? zWm-OyD1xT^{x-e!ncEW8kM0$Y^fo0#X@1vt9d1)}ZrRa#xkJgq5sZW3f%zkt&ukE@ z4xQ;wUtl?<303;doH%Ln$0hy)@lgp^u~7;Krnn#(D(x-2qP`qGELG7ItW`6A9P#^W z;3bwTYT~3&VEHIWukQFx)IQG}3b_<_7m~wV%}Oqj8}5wda1@m=M#*As#`1mY2gw5} zjd3-ZXpo#ua&7%T#G zgF)kze73!2j=Vi{CyN!~%Z>CJ1RkpEJlN3t0pjBCAO64l@W(B6NBMNdUvF)9+XvOx z*mG@i&(!TW-C8Lnb$|FUp_Dnpwc-!Ns}DL<;of<>qz^Y+3{%_GPFv>EM;=`MhbNPP zo`L+bC+wuf&D3A<-~vo&f`6l*p?DTpuBL>SDbk!^=geRhx0QcCu*~-_A79sT=SkDY z7~kEzFOuWNyXHc^EyR{IuryLnr4)U&!7Xq)4-6A z&YdELT;)33?VCcTacvFGpyiN|<|_9}2O4;HmqIplM}RE(Hx|{>$K?CM__O=8jlK~b z6v$=o00;Aso<`4E8VZq-0ZyP_LW^}zpCF6gmSF{kA6^J*raZUm&LkWG%wA98|p9`!Kb9uWL-mNhYrwkeuJj4{|a$_?+Y}XZiABgdxqWv8QW@L9~!4 zDaK$wnW}S0x9?6rRsGeJSy+>zO4~7_5!NWHtwO4)?e2Cd?>!!g7tN}I0nmUOD{)%c z97G9-DmE)O$97{9RzAnOV2ToiZe8oN`pm)y5=>jd7spIuDr)>Jx8H2+bD5>?nbg%S z?1$owj7noOozN|07a$x*B)}$ox4x2H6cc10Uz_$Gma-RPQsU|1=}}OrOg8uDX1BQa zsMIj@R>Voi?Gx4?`wXP)lX>A!w^ZJ90BC`7w{uiryH1|?m%V9ZHb#KC95xiDuK}~K+TxZ3x zTME6GQY(?FTse)QNR6tQ#|AWyFlFaPPTo^=XI$~`5Kc?5?Q~gpZ!-a1O9Pj1#_wlQ zjqIlPfA%UvX7+N!JUke!k4mc)YJ>Y1<`xN~;2*Dk+$}cAK8yA%B6V;4aMuB71ao#t ziHZxt*dhJewl7loEc}8h96!stJt6w^{^+=GVHNkQvdkbwqvbLM>*LFbXJgi|Fo#5L zB@%}hmug2A|FaKis)_ABnC+igd2~{IC0D@xr$rsrOMLLC%POUOZ=ZR99UOR$=+|lSKBFvq zH`m=-k)l?AWQpwUr&`sG3NEknuifwo6kRU?B{2t%I_OU8Hb%3YgDu!E7>#Jtd4o#)vAj{sf{~&GQZwVX97dmL8;_fzdfDF6J2CF;p7}@z2F4g>tg@(nZ})T#rAmd~FLfd)xnfkEEn{ ztoa?}uWn>;;a$3Zu@`}8vL$C@_34-fx3YUl%sU;=96m@~mWn+_=OVEqCau|<+~0;k zJ1Hv!?viMr6NOFHg57!YS$2TS!nS?Bl=6Uo|F>WRHp0A~r=NkAWn*Z6C`m6Ax?`L7 zT6#fOhSO2JenW8Z$r=iSoqNiZ%N8TAdc{;b+?a#PI4t$RA$Ibohe}KM7~RmFTCnOG zvc|gO3@73fc#}BNs6{mKAS=#`HfG3cKi&2pOG;kuZ(Yu|_Rf1)ASlUUi^oIMCd(rf zZZpNi^Obh*N5;=FHC>guBs+@IC79^6>TQXu^X=w^PuVxJT3@-teIcsp3kS-a@8!G? ze7RUu#w{y6Z6-`V{F~|7G$BeVkvIVg_SpNhUuC!sdmOa=wT#P?t^F6};+%F?<^$gw zBm3;oPmEnI^i*I)@Z5qZ3Z})3gv%9z${KD19`0lwPK}uPKMZw*n}(GdajJyw0y+pW z#J(lRLsYcIMre?F@9tCgc}8%CRU%F6$H4DK!9A!)?s93%BO6|A_U+k4PYJBE_!MlO zX9C^d$U9N%kfeQ=H>IOnLsRONR{qR$TW>z{5FUaDry#D5g4In=<>bycWdkdi*#5`q zUHcymmApBu?lkWSkT{VtsM!5G)0j7TDa^Tfv}zt;Brjh>43R{+3D^-o4p20)Xr!v@ z^r&Jn4?rH3zFnuOt^Z_!{(VYEc$)p2)xrs4xalr*cd0D}=lgrTp#TRGwp5BfFF@ix z{D+q$Z4=eW_HjCg(yDaYkf9cQD*Q485zn~{x1}3Hl;w)q$YfW~cMb3`C}GB9HSHHJ zdIAF@=I-m2Ri&f65?fuhG2DaF`a*r(UMomSu=5*bTrSVM3=`ykn67ax>kzmXcB5c0 z*L5s`xna;zy>-IxT(!R1Lgf zJ9L6P)1}aj#7`^N^ahc3cIsj=m1U0vnV}=7U;3XH88DdysT_E-yms&J!aSn0Ok1?v zZfKjuhbm=K|EldiJlaS$!`DI<8pwFl_kXO`AIU1Qm7e9PmYXrTV8O*B@} ziZ=^=qfX#|tlcWZ=d5%2!7o*dW?xS+Gt-6v#>u1>Ic3x$HDQC%A9gdrdXl^+Nb>2d@r zVj92DyQ=o=g#ioISMgCsCn&fCl-d5OctU>hc!Q%>iQ$0v1=*VqcN+#^pT=zQuic8G zvqtD#>qBrFSBe#xLE4oX21~>HcV&Wtz`u`Q3AkR@ zIB^TbQ%JRg>UMmu+`MZiIsdCJg8z9Q^NF}r@&FcaBk{5j{4J1-0lN8BjzH#L{DAX9 zel2p0iyTh<%rBVM-jd0sU_E^TzQmnh)*3jlZys$b(SL3P} zEo0+8ekTv}0SI~<;6}tK<&C#$Jm;&=pbza@*i-=1CuNvS_m+)}!JIS$<4Hw&BLVXt z-kG748dGOcLCJ1AY?l|B$2BKz>FJHDhm00yG+lwf@bJ@LgjJZ$LxmBgNO+JOC@KlyzZn;NCn7s6u>(|rP{BUjinHOJxT`;wGf#ndK*i=o zL$R)~vjaNGc8yFzQupcAgqAFU5c5PD6NpWGwZT-EflW^q4AC+#BTWFFqsA2p-|go> znPYNSicxXCZraQrYs-J^lrNX{gUh8MDdXaP?(d26u@u*qeqQazQZJd1UvO=3m4dAo zn6m>ms{7qw`!d0Y_Qz?B4~EhAaJeUm3}a42a5~|NR@_^zYVXVvxzCehW7A@4qaX7c ztr>3KAh-2!jXQp!MZ8|5YM=fs@B?ZW6o>zX!#^(a-;mQRdzODR%dY#8$m(rBTjS5E zy`1H4`4O?EV5-t0&;^L4~{c{~qfUT6C8;_~ zJSqRyib*H_EeN^PrbXjIB_wN}CQy}hSSU2#SIS2R6iU_%{#w$)#_`W`g{P3g*(j#ih67M5y|CVz?irGC0yrwx-rpYnzw; zDb$Oj>D@n%QsOsSb9AY}_D*m(-x^J?3aW$BIpaJvxwG(beCJYI6EJhcC}s-ta6j;n zHlkIRlQM>R`s_N-|$sJl|P7lD{u)OU~=W*DoYDHpOb+a|Qv z(7z^ymH0PD%A~tVNrehRveTX!-`Pmrv-2HXw_SzpS3uKbRTru9vsE8AdPEmQtZKyV zG6qBQEXP_MEBTHqg`gLkxwlZQaUN;R=q{XKfRT68jqf~|Q+G(bSBVlZ;L6=F{OBl( zq7Wr4LonlGiiLjFMn5~;caU#z#r=C{BNcM9dK5E2LG_f7iBqBa^6jUQkr;g-U~Age zdpB-wWHW-=yNM(4Ra50;X!=`Q8tuD*@4B|QJ1emn)V2GP*`SwZpOFH09$WKewTdjW zxK{YBwpLZ`M+U++^6u;c*Y+!XnR0$DHF1aM5|gf%oIme z#R~}^{IB#degzn{?_OD0&aODy1aE-^r%gnjOUQyh!1J27yw2w&(v%dCRH$)rs?+24&XX=Lx_2Pl~Tfvdcj zWY4nN%ZG-C0(6%DSr+WueYNG^FvBJmculH{6ZS}shz#pSe5K9@pXjUqfb?)*be*Wu zVMR!WI?ly5hkh=EZvQO(x_NH} zf7N|oW3&!M3vtATRG-ep0iZnHHVS=#T9Q4S7rg@XCv2muMsqjm4y3=e%egRMbc)soo$&$HiMUASVr7MXhqSzKYZi!e_Boba08*# zUu`iwvWpq`O_=y(&vOvE~X`+E-P{oHd1S6u-lTfFI)*xsXOSTa86lBmTv8B!H(Y@3*3S=jWkdhYK*fgA!)M+V5lzn|k zv%xXU$&b(}uTc(BJ#%cTU4%8N=(IL?8Ryzp^2*_D_E2(5O$eW@d0dY8_#H#qiQlWE ziY_6~M+c`-L!UGZT%6wsqor2zm0H$owr@D1*i^kwEorkCHSs1R6N&oBu!662N^=zQ zI8)1<4I6SDXZY$46?+yNa`*i2hY2NbNel;C@-emL3v7qQ*mW~lniT$Vol5mA*xS4N zntLS0iO5&--%6ggND;YYy3y|IJ@cb7=-G&^`!nA{T)s%5K+Qvk2;3sLuLEUaQ4&aO zj`S9X8z%+k?L{ zo!L@l8Bez@T(-8FQVv(NLHWRbGD1ISEuNhwf}`of+6her2(1|mGww~3;R2-STwj}+ z!DllcHTH&_*QRP$_KsFq;aChC1zg|_o;t_0wR9Efyu?qpH&teCo5b2_l?Y{1$*Sym zyNrc)MUZxl+q8ABVC;1r#SARxD^M?2Ma(f<$|}!aH-}*IW#2q7qTByxGi~lpUPFMc zz)UB1Ik%W_V@u*3babJQjL-Ln4L6?P>zB2>Ag6bfj1{yswPS&zn@4F2!gt8^o~aVA z7*S^l{8;r#kYVj~kU54VK_^qok((abOE~*MlE*Gb6~oTX-hK7;iOZ%!o_e62fx~dQ ze&(00aZ{~96i{o(?K+w0)P^uTt$X3WZ9q%akUyAsWzYY7N0!Arn&JGLIb5iRLT+Ox zabRQaNi$3c->v6Rhs8bb&Ga#R;myi^#y-X0JH4$fiEHQl@3mv`&I`=a6^zBI7+w9@ zpb7VWM>HX2ouBUXCAhOX3`sU8ch##z)YftHAliM$j?#iRSX~(CyIRHby{RiGM&;7K z={!?B<+FzF6%?Tx-Nc4-Rq?jGFEz27wEbUx zsmVJV%p z1fXC;Ug@sp)J({=+fYle$hs!q^pV=f<^%!XWK98>bTO&#@VpPr8)fbmrwwO%@hVcC%0WvtVH)_gqh@GSViL zUrD^a?yS_1rOkZ5eNq~^^W!AR^oO+#Z~>Rv8gCquohN~_5Y_nh&dcvpzw~jb>NU~n z!Mq^O{kU#l3$?FBNRBzfRndb=oMUPlR^8`Z(b zL1rJLc4D2Lo@coX_Z-eRDxl`_k3iu1tb zRqg8tRHHs!(9PVf6$5>+Vi35&BrDlV`zDc)S0G3OE|XP3pRy~01?P*AP*BL`PhE4j zifXLn715BS&EJeQownM&X#6$91g0}yXx1+~Yxh;aB^MC|XR^8Xt(hRd=gIyPdE3k` z;ffR-LPJcEFM=Ns7rZvs=irbFvZ z&t*Rbx44P*ayinw4Md86$d0`Tt{|W6-f#Mlp^~wrC0~Z*#2s4C;})U)4IAk3pP9FR z#UX%%j&(99#x);_gyjm{WmDu~wm`cYXsdTdMyhDZTh5Nnro-BzHs2gq%Y$&4zc5t0 zeMTSdRL$1z+>_vmQ-I5`N_O!3l#jFeDF%79vf?aebfzP|Tm(v^^)U{b%D3nuCmyw_ z{rvF&$~hQQr~cGRzq~4TZ;^TL?mSwzIa%P=%6aAPeyUX|Lzu7F=%a-%??t)C07tVh z&+v2A!!#iZ?{DevDf(wGsbjU$MO3-SryO5fC9`J?Bx~!?wf9QF=XFQLeMDa7YV=+m zv>zcrYf{9InHuVZpdT9z_}9?zqR3Nh~-)& zmZ0(ltP?x|70QuVI($ff8n&tcHdcl`fL#=M5HO?|z<;oAW&N-)PY%j$XiQ#LKdSt| zOK`x+D=bJrE#QeR=(*I+u&Q5bPFg)QqJGeGFS=^yV}HsI;zu7lVM-x_Ee-$S$vb(! zA3n{r7G=Nd%r=RxL8R_s>~q0lm_2N~hx)p)h#a)isfS9Q3DiCi4jXK@avunA*nQtkp1zy`|!z}ys|7-_&LAH%&l2%j`fS>25<p!ADmC@tSQ*Xyjoag}A(wy;p2dc|^9?6;Pm~)rsEyc*dAml;UaxhjN2lnI zn_7|@+CY=3y+7*USzMu_8j5muq?j}EDi|T1e!17>0MBd31z%Z$vUW+o>y!=xrE)f7uK45xHYr$Q~Zm?u`p2w z;pVRPP;nu7Q0tGfrU~i6L4%ZM-f=48x3>UdsPO*U0I3Qr5t;Wg+IN2K>^Uz!@)Lx; z9bFrzC;lEaPd((C?y|dU3=cd>6eh6H`Rp3BX#_h+=&M_=mRcBcQ4%8@55$POV|d7c zEa^YIi{wI|%mrkp<#Z+c>dp}CnQp2dJL6?-32Zy%_-Z`%Q#z4!_Uw`oBhw;`6OOl< z?NVKf%JaOE82mUbmsQz8NKChjJS?R*pf*@_*JYSa_j);A8wYRxx8G#P>%jAt*G2OW zP2S)A&r{$w95RkUcQV1~O9hI@oliM^zkOHxXP+C^Ie9O~<)_FHi5GIWOW~!=FQWhO z-hxePsjWR_oZAdS%KuD@i-_Sj$DAiqYeK{_4cN_REEy1N>NHRFS|&`~ul1vDNz?KkG< z8_v9qny&|Y5!22Ll=>I3Gk!Y3M*{ei}C<+CdhbM1B%efh_#ua{i4{Y&c zas$r(N!C;>ccIL}+y1a`UxcO)zgG77mNaA4V(8%^UMx`37d@*dCMh&tD0Y{Q%pM@HoF_Q z_WpPU&(EMF1(K|NHRW87urf(7jTJW!KQ>lPCK!N>>nJZhvGJ&=i!oywnz&=scJ4Z@ z`(ffl?_1-rou@hUGh{8f@jXwrmrJSXK=i$hiy)}sqFI#1E4mlVhjEkNup?FFVOpbo zcUx!tDixr~6R2Hr(#VQ=qbBn&abKZ^OJ5Vu3*SzR$W*_fnW~{7P~M=h6Mj&380`!D zc4xZ;x`H_O1{}Y!@gu%H!`+f3+>@@Pbo>?UEJbrPqvJm2n=@>?Nn50_?3Ib?Ij*UK zuHXwdM&QMxu3JP)V6E0@{ZiSOn;K2_mP=CqNnHc_kibxXiQDmG-O%>d)GeHVoKWLP)wD4_WG4vZAqO6}HWHrtwFZ^A&=WrA5-IWpFkVb)%HK z$c5z@)m4$L!qUuiQ6UM5M?}th<&g6c!BD#&G0uRXit0t8b196{xgdwnKvoM-0qZAQ zNzOpfugQk$K5NUL8E5Qwft&=5hgmE%ikJBh=b}byFot9^D77O1D{XY}VKx>M*e!J&7&~=T~is z9GVkB|K@wPyOftd!*c4*E#6;ptB)K^9hRM^P{F{gb<~4vtlMe;mh$Jp5{k--3IzVZ zt5+{*)p6JBF5kZT3`>hHLecqA=(@0TQ@vFjy%_WX$t&VS-oEF2BH~JMp&PNwOAv1a zyX6TGaz}V1>6V+y)}%<>(+fZmH5ko{`S^rTnI$X@KcM`*{zKvxXfZt{TWU%I6y&LH zUKb+bEDk-TR()yxr1fmA%Uq(QKM#|H+@8%8;J#V^FKW&?&+TfXFS8K0 zmt3GzxZkeZpsFD^l$B?MaM-<}$k@+!2Oy7YPa+jkEDCz3iHR3#xodt-Zb8K~N2&uv zHtX`Bo#}7jlp}o9(q$j&ENWQCp5Z2k!jVGna9+iz=}H*IYZxyqLBC#m z)FM(pL8y`P5&9#kv|vYrCo|)fC}gO)$FKyXpH}2$e|Hj4r1E@SVuXy*H<-^bM|e!q z6nf+(7|`9iA^g@J@^XW58;ma5qNoUBc$1)Cr_zW}s_>0E|rl~AKN z@3w7nPjmEOy(p$gqrl+sINn-xjiIgO!vMoms=h*{+l&(v@wMA6V|T-kr^fPhf6s&P zw6%fUdB?Rk7N8{~O08MgPjD)zbX)eMf=@TbbLV-(Jd)|tHo}emr3%Tt%IBh5n9W+6 za=}!UXa9`e-QW*D=+ymYNjA5U>azRRgROafrQe=5_oJS=F!HGh%0q5j+v2A2l+)9? z-oXMs{(#8SLHifXrqmJITm_qBkz7@`LtM{A9i4t@>hep?tGZbZt?eeWpeIIsL+MWL z?{@g69*G?w+w$BdN(zkz6^+-~iM}@Z84@qR;~Lmqh=Y*ljow=JnWH7<^JK1r7Pqa z<91?j2L+!B>{lgqHII%SE$^JfWcYP#j{Q>Re zqKko8#Z<3{rMHX`WQMPn?!A*w*`S2DjuDcB`|r!pKdu;!-R&;+sQ{{<1M$yDyQe^E!tH%W@n`gyZ6}QM@lD$=@fu2@ChcX1 zpjebHb5xxmnfOq1^bQ^eN2f+){1+z?YK)dD#}+`ED~N5^VBtssu;cGN{eZb8058gvikM!)%{ z6lpe4Lf|0n@nk6nxsdrYXuiO*(ElUqt>c<{-~Vw!K@mX^R9YpZl};I=baxBVjkM%Y z1Z2|9C2x0s_(k(%byqyxyPhfaO^O**rx|d&FIg4*@ciFGOEcqQTlXutt7t+bjM|7vwgLN z(KL>?dCniB_!+!ou=16XZqj<*^XTzgI$K}m- zs;9aVNKWtYGr6LMnq4pAqbZy%QrV@jDQdE!wPWe9uN$RJcMbSovC`a?_l1 zPj7S4q5Kjh@_bU#Jns@e4m+tbW&~6)UVkjKJG2Q!{Tdh)QHM4oG10yYyv44g=QD^y0E(OE9@d z%b^O<$NLTGznjtJ3f&Lx@Dqp`T8H2XgMaP=|i#rnn9 zQR0ve9_Y~l1YziH;|?#salB;wRN_$3DMvMUZHS&=fwOxJ>)?4O<(m6&{6H$*1^LI8 z8Zh72SKn_g>)}RJB!9`m^T9)xbAQ}s?Gj^fQqyH4eSPkwbQyRtrzB4xcW)PBk|ES3 z{J?&G(YK(BSlD|cY2Cfq29gIKioe-i7;7wg&G0lmRvqZc&#RIaa`Rk@I zi6O0@GM%G-B#0t7grHGvW$GN5a;f0K^Ajw0Etl49fF4WWzwX zj{9?a8*9i%*e4_0UI2XRcfm`I#a2_&PxF}H0Z~)~C!0d>i97N2#)uE~E8YJHI_g+{ z><6!Tv*d8KDF~^`4L~l&pudev(q0I+KQ4qyw%WvL{v$9vtdgpf3`UcRq#HF1E+i|e zCLW0hXO)rS3a!sL%bFC2@PA6{Pn=TwsLO3SC<1~o5(srcWzX%6ZQ4V*O;J1YU6d;w z=^n${#aEB<@FB4azJCPa7JrLBAN>8D8_2)h75aGOMi&oBx9j@(Y=tJj>7FiE)r0mf z)6_CZ)yi3boJ{MlDLyyFgAJ}>h;P^#TK-;Q@MiS*LWVj}DZ$m*AH)`pgXNh%XW_uv z=Q{J({3+>k`U-h++os3scH{%3Kx|(MvDnjZ6Vh%BEQsnfHM)J!?bWklEaIn1STXL0 znZ-c4H31VUAbX2ViB%r+Fl;ykyy$!@hs~hA5W)Cj;Dm-8M?*fPxUcVWA12zE{ZO-Y zo5mg~QbQN_Lc78HQ0-IhlD@Xa_%e)%*IXfYY~1 z8xWQc8UE0jmAKmey?WqIL1AA?)Eq8JV_8z_{=>0czkO3q@bw?^8vcmu+Ax{x+g)6=US_RjC_lvZ1y=Z~U~=!%A9IFsy;LcWO8DV8ab` z)Y9!)aXMev$a@31E4Ed2EbwpnAhn9T%3#Vxu7&DHln@{f_pMZ=ZeWv?RWSXJg zj~k3RlKTq{J~x!y`EQ^)ug!d$$L@Ejc_)$B{sx2AM&Ehbhs3e1l|XG^SLszW4{gH( zx8;qsz5-wGgaR^>g)Fj?XqLRp&Pc!v+yOl(>_aP~- zm1YM*$Jm^*ZVqb>E=JZ_E+b%@fwsQy?Bk-dzx+T{DJ5yUcJ^KvI5q(tc5UW_EnqqtM4=2CC!>3Hg40qR-XBq^cty3ou4DQ7AyZr#t7RAi#IjY z1zNy#4jn{ECN{Lpge}(m zqu9bDj{FiACAf3T$7uhGY~+1!=9D`QvA|N8Ar>h9YU>zjk@Ge|85e= zL(}F7*wkoO%NoTqrqks-<8jrfCHX@ek6ZzPaJTs>-TJ*Yx!V)ZOyNQ)mCY8%xy-Gc zW!%5L9X=XCE`WSWpQzBBB$_xEokZ(Xdy(S$MGeXH-9x+2Sy;7cDdp}{<0srR2_{*& z0kG#MOzl5}(}&`C3*X87#?2mWoy46^sk^@+D7>|~O#=Oqoiql?IvPGQUV?u1p- zd^Vu_I_H7O(dU+6h{-y`Dqw*v6p$?bq5M?PC3UKZ&ICny>N`NRRtez(&QVq%a_Tnx zlB$l#OQRuw4#KIPP{T|FF82buuv%c#dFeHkTtKEG@IU*hOS<+W;o2-vp@VLK#tWob z(SeuF5&(MMrC;Qw-0&(_7Xcrin6O>w-G|XIHMAWd0y_$8%aQ<-?zaDPqqIxE0lzHl zDKN@i?0n$=_+KUep9Pi{kc^qKs5ITFD3(8YY|pai$(=$II)PuDY=`YZjt8OPockoj z07xPWsS3jZkIqoxMT-e@m71#);+ltTuUc-Rqb|@151;su{dKGjs)j z9jBB@?O%+QDs6(OyCGAfRGYIPOjgxL%G_M}^`ifN*3pt|QBlEK`VD26$^Q(rJ^^1% zb(%~@u{Iyy07T73Cf!6e*FyLo-$Qic<`Yg6g1wfreQ;Kvh|)+Blc_-irhW3|h=$-4 zlMu$|V_*{grPThIC#Az$0-CwTw3S$F1vfI2rmpp**!uQ~qT+&jF?RtubX2JNsi(5` zHfMq&!QV2xdW z>OF{tSC{14vT4Ti;mz%QVyf_y9c`^6;wrR=k==*q+?7eveoRe>iN8j>>8jM*woFvw z?g787GnOs;XTA+NQBo~%hdZE#NtqOZ$5NQDZQ38~$3u?8zp;p@&-EYXHo2>KJY~k{ z&V4rY6{Gk?u~UCo3KfsaE^yB(l6fAb)viZfXGsuth?;n(6ThHVDcJg;k*9aZTq6p4 z<8wGd`+%Y%tcSLDU#IIq)QQhInr_@#QgVK;G0aIlE8b$&9g5PbM6a8^Jx+Nx;?Hd) ztzs>2{Gib_pM|v$!dGXHrw%l*NO`P_{}HVl5YgS~(dCxQUGy?LYQ4_me1*sP+D400 z*E_X0zq^5fUZ-JwH)rd_FP02acMqc`-noqQeXJRrp)v=lx>Wk1p^xHt{@EF2i%)Ug z5bF+f@Mf6!R@acQu2i6K zb5Uf{$Ous#X&tfEb2Yd|&D>PkR`c&iodwY5PZhr0JcimOST=sB(jl1-JF|i-ndC)A zrMpEs2mhc5%*}*r-b^}1UbKV9*=GZh&V%`&@fPJ_|I%~zSrZJUKt0b-n?K^~=%fjU zs%3+r$&%e+n%oT>56x7?hnHflF$oRWG71TnHwnfx0<6z3F@b`A1UBmjYxS)LkY$75 z)sFz4C=cldryvwO{}V55*AS%2nW;>k&yaJ6ce6FkG4i&X-Y*|kCLT{* zyUUx%8%oj2L%C%ZpwxHrro2IEQod7;>o`Kb+n>Ga?Klk|X;Yu8w`XiwH1Y~_9inhX zUFf=%*^UeO#T0Hh#okLIBgOv$2bKI(oqcnBz!olHI`H+3>|`&8Gtq_0&+s`#_(QP; zC5m7v!$)LkdKPn+$XYs(Uueh6?WlEm zkD1Roi$X1JZIav#)M7dq!{8s@_)q$t^#*UaiCUYOD+AC{$W8YzmZuW-+{cC~CB##K z#A7~S>cOAw(nJ6LU{DW~qq?BXx$eh-BbZ)>`(i9yBNEKZ@8LHJy{K0Fjm5v+UqLeJ zP}LP*XTUVOSwUqSuNQWfgT+Wl31sZS2wtPwDWN?FVka69>8bmuIEvn=;)lJ9{%?RS zG$MxTO(b4U064O{19zY|x+d^n)OCNoxNEw5JL2rN&c|zqr02g(o0mrKO2eAtUcErz za$k@7_eUGjqLv~U${`ryv#E+SCRDQ=a+Os2;;2mXS}$>LqU5ds2$b|G7&oAw$S=)3 zg{y;<6m+rS^KwU*gUlkjke^rlRvwAGy+aqV=}DtHD-Lms!#6+1zvn)Qirsrq6}Qlc zZ7ij?OSN*?WvZ%cusmA+v@at%chNiXIarZD5&}Y_t^rN>r&p?QS9SO6jVTY~QoTa2 z5%US1VUZ@~! z@-OPbyMyro=MQWD6xG292@sSP@o~kDGN&&V7bcoerg4xu^ zZQAipMj@xg){=8${|Klx)9`P6u{<&5Em|%PkjL14kk3uqM|G%Q5q=%3rn2Roo2IPk zPXbNxgm$)@Y}HmWsQx3U2Na%oNO)Ej^5hUY4fyDzF=E2i(27iaGw@e&)tFA+uh%+W=gqQM9A}Z9nQE&;H<}JO>yS zku8iq(ob1(6N{O@@GYa#VWn~HpE)<6Eeg#DA-dQ6HC`OEV@|(WKlhyJB3Q)(yERznA_nIlOBgga8F1+siW<)m^U%+Q zbd88$%%3wIC3VFc$p6HDnx+f37tQrJ_7CxyOZGrF|Cy;Xo&S+%%W%sM^@D0X4xw8r zYO&RWZsx}FYXA0LxG&{hgFm0<__ZrC_2wh~nZ@y#b0V+~D3>OQ56RE%6fB!nn>s8g zX}cyp8BpU$JP%1>;r;qEn5W)%)h6HGq*1l;(}j@x%(_gwHwfwlx}P|do1^c~HM%?l z^I}2fe*|K*#m7d5cw=B-6PUaHQm0cPvZX0MQeePeQieP__`?7qMikA!K~sk~`YAa1ufPP@csleZL5N`Fb3tcGQ+eY}}jh+SgLPA?|g zmjDXr__rME{wH0B*C`;XKCSQN8`47^0kauj3!sHK>cJHEehDS(??Z+ariiSm9VHYq z7cN?hR=Y}t@dsijGqWe=(ZuGjk@qYReXiA=o(&j``O9$NB*cnuX4x9df|G z5G)Vn$a6yq$tiwPA@+{_LlJ|7k0O#fZ_f1;nt{*u2WxOJCNg!?fU@@R9|5kV{is}p z<)|3{r@Wr!i~vA!&@Hp{y=uLXJDxhY6*b~Dr1HtgRDAH}uEljK$u>%eJ>&@Vc($~| z1G%D_Cz;^9MaF*T?(h7k&et~kwYX&i`T`)Gcxg*|aYjG!+q+o|>mPUidy)e2hAJQa z=q#a$^r9>up8MjgOcCb|hUXcXt8O7$+?;6L5^SWH1H5vJIzK$kxq=`kvU1ot&nI@7 z4;2}Ae}6pI`Q6P!S9g`oR+-hjq}-osA$5ga>2w)N+DGu=KyZso$+nz)Dw}M(lw|qDP9ToCa?q=U@ z!6Vk(leeY1b6tUUuP_%4-&PWOM7pm7m#`6$F$crwiwAB!mY^Hv649^x(l7nzH)sDk z#Lt#Jr3bib>=>M^XX%{>Cz&_t&q90$A>{i12&h~y901*FKp;tDRO81uzNsBQU>;kR z&2KGU@utPibvqA!*N43PD{+rL>A5~4@fKoox-@virS!#?r z3GOB(MJSh;^}OyKs}DKF{$dM>Xy!y0s|1hn6>0()Vcz0D7@^kZBVA!r%!*n0P^-@h zM~ycxu9@W|4x~wiY@YM@AFFQWAL(3mXptx~@ffO2s1>Ci@c2hH+Wegrh+99`)9aW*?j6$JL9pgF zHl+UO)GcRV!d2z2Yte56Dc^IihI~ppn#0o$(H|A*`*0QC>oa-oAx9lc7s!aF=kb*H zq{B4ZBq?JdG3+#7%_cLQ4SW)QB)i0<+vBpx-U%;!Z(h0baOnW z11V9S-$mUo*5Ni|%H()me$&+rJUT3Hs!m$^?uEux_h!prk!yi@>g zGMaMre6)@M%|VCW6>H|z*pB`h{%ij&&WWd#>$5Ub-s|El{LQ#^Q)~T(h&4sauIR|= zi{9Yik|Au>yyJMkXn3L^^h2!8IhmU%b0pITi&saoUHv&u;q8>I|q~B^Sr+HT!;BV+@K^NAt zd>RE4KIz2khuHQI;DgX)R~#LVOFd8g&9>_jl5jhX_&Vky7(8Zb@oXb*fYz%c(iKcL zcE0N3&l41nN}78ivuV&HOgloP=62I_xULE@)TikF4o1l;VopgJphsjTPaJ@{p5}Di za~GrXlaD|U#wB~nDorE#F9DhmfLEWcA__qA4~ZXT+82mqs?sd4|HqgPY5YSZI>AD( zR*}vi*(O-fsk{EOTSCB2ob*Kvz2nQ}0J>To-KtA0fF_wdn4PBa(gqte@0VRZ*!~Mz zsy*nc+7?g)0jrliI^xnV#>ruaJ)_5^M zzYqn8Pek!+my-mCyif`U;7xxSvC4HxhvfpHs04hHaIOggopE`|&|71Q!a4+>bjB%s zcT5Q0JScWd;4&K@BH$yfdyF7ua3G)&C;twQY0ly#KoW5Y9qNn{ggE(uj8<7{VpVk{ zp=@|x!Tsv-VnH$2LZXMRNSFiy&;6W+P!$guPK@=@f1x0+9CPTQk zfQ%qQkMA&0rxT&Ki|0;bNKNR~=TjnP=}=XVX((SiLXHyOd@#J}BX+eoG)o(1(W1^L zOE5&!ItK7l##DgX5{o`QF-Rjxjix8z;CjXrgNhCG0a+OjHEYeFBY;74vR`!95EPz| zb?_ogVyr&IOsp;S>%P7{2EWF+CX%n|`6^PhzhQ(m;E=Be>JlHVoK`!f&=A_ZY{m}I zu)MeW+?Y|$zR;f^D)TZ+&pVkQc^>XxI7;MYVB3lz`(E?_vA^}?RX1#rm#sD^fqJjr{95D5J{=jX9|hZH%ldJgjg-7rlJ z0f%tq8KkwR>a|Hf;r^TA^$l5uV?;IJ=lJ-L)!jIV`Yr~yu9c` zgd{8h`KTU9|Jnx?b4q3L9=T*jea;e`yY< z)(*2Oy>VtJW%V(qDN*wk?jM0uWpisNcB*$#@ijD?t$Q1^&K3)M*+!hKgpH6lcI6iH zbEb1=PlN;Cg8b|5MCm7}z!sr7ENhwAiK}NyBO1cS~SEn!{zHx(-2s zM-vnDhj6V2R*(GmE@7|;m7x?P^V58m6(e;9F<|iT0kx0z|FpZ6-iQBc67y2kd#=C^6kQE8@@(W0x`%ok*@nU`Z`}A9Mlf|xWGM(PzWNnnzR}M*3OH!6 zgxh!u?aq{OeVF$>pKO`i69`HtLNy1Kke)oZv8(ChlN-I49Ct#APDMmOB=tV}idCB7 z-V~7R{EY1$$Um!|vjn9bK95}%v zc~74GX&aNWXIxpR<9GQKsli{;twv!Cs%6wGOTm<*d+P}AfTWVytDAHCBTs2OpB90n zdEFe&;U!kH8b$)iscs~)%hs7bUkE#&x^-^gqQh(WM3rNws`uVX1>;m!B9rL=RlRgA z;mIq7m4!$*O96F3izAKpZTJknJNZ}X3lIDZl8Iy`d+*M|DORFD@VHEI=E3o6O57oA zon_CU92tDOB8Ax9d??F%C(M`)3%r$cJK5Q3bilHi7|J`t1we)N7JlgdxCy+4DHU+` z`kZ28OJ<{8Id+Q5=Dk;7O{J@=N(qpOyyBjvE^(|HU9IT3~EJN!VXOaD5N{Pml6zW!58kf&3yYo-^f9!WNi^%1;};7p)Z}7uD^3)2U_pj zA!T`ye`1^<#;()y!31TAJcdS)jhbK&V;g$psQl1F!SgJZ?Zm|tqltrJ`i2Fv{M-|H z)q)wb=TF)^s^p#!Z+;4!%0$Vy70hjcIRJv?16>SOuYi7Xbmw7Xj$N+fT%GJ?o}x-| zkbb$H!?e||G(~b~@ms^%4;^N`b9&n!@MYZb7n8t@(BQxW%Wg&bROV2}m!5TEE_h;a zC`Sp~q6ep<5=Q?$`v!UMu3s^{4iv|QF^094afO3Gg} zuCPf8;d@fVnffUPL&neSzC<0WIi`6!Z0#;)(^7t7Q!MfC(X|`+48RUsYXbd^>)x{%tNd(~BZE z+|Ep$4b`k@?_&L^0!2mg{4xZbPQ=mzQxblm_gS$Zy+{=Pl8byM+|{m*!`Q$SsT+!> zo@*vFPW(Rh%Gg75yn6Z=Tx#{J4o$y^sWA1xEjw*slQiIao2?4FyjjNu z?FjZV1wLdW&Kc-m2kxHx2Tgl<35)K#Wq&clITcOT)_=#96XpzkE5Ej~h9ByGt$4e? zNx?i?O3dW7t~p0>;kRIx*)n~)ssY8}z3)vk2W2|y-;#fZO|=vo#wZ;Je{kw_0dZUG zz9v2ew>J_B_F0d%rrSIle3usv9B6B*s#Ibh=p{w!Nyz85vGa45Cn}7oURo?#MT7Va z7}xjo>tU)@rGC%r8(J2s%Z&-{Q}7u7mEyqP1$vURa_;nA-88NsRF?5ohc2J$Q_snX z_x{Ab>|5}rhCtN}zF)J(l-lT8#D{Q;P#tyJqAu}CoZzt34{R}0QmjB9%3fRUADb*o}n1RsLS@}t1V>X=J?x%ru^6f{FnwGV^bcoxi)q9=iKm-uNT z<$^l*V__ywoI+K&9L4`vwB>=|j{iOaF!Z}pfV4`^f4pEq;7Zd1LInRKD5c-H6x0Ck z7+?{@fAd}ek+yOe_%nk;zVO$ZG)*9f1ei&JiD>HoV(*bXb=5K5OW%rqeFU!YTdhnh};BPv102Jb++14U<7`lur0jLjnJ1h(wz-?ea!!C2Ho6iwXWyBLP3Z5Io}!qi|1%?D%v`1vAKd$$mTze zt*#jLPdA=xwP`j5zJ}}+LbDY;d^|kAAv1o>dL4%7)3Os7UAT@Utn%)x{)}d%8d=h! zOj|t$w`1ypzw5lTW>w9pLHzU)Kju@{@nBJ%E}P4Y;$Nrk zFB0#*ja+!tK9$#3Fm%`IPNpglc>vJsmL0e>ui$1WXDR7|IRaDQ8j00r8(>tcwXV^$tFfvEo_U?ZwRuokE7t{VA ze1&S-TVfgP-(YTVXQzK-d_2{p+S2DX=Us+e;}!V2_6c*aQ#jsum7R~6=KX)3OERK1 zuQz9GC20DEWQPl+C71ImcHx3_9o~PJ6R^@{i@b~LhvgwtyMc;}#M>^`v*k>II_@i> zILo!r(U!-N7_C~*&o16>5EMTGdSfHTmPgp@+Mo^1*LeZ`q)xH^@RvM(?t6c6Jp7I( zj^@ASnuawbbq(YK-t&vGLMiFW^E-dI^2;0GX)h^Mo<5&_N>#mH9Xslt%I$5waal|D zju(<%tN$DLXYV+$dy#>lxCKck5~ZN|XH@99!8m?MBK3!m+fSCX_%ctW5>8UuQs=TV z1BF>V-}!rPEFCF58^&~nM?@DJ2POGO24>h+beG)*x0{*QLTxR|jUiAtV#VL)3Xuf! zcT~1-U%K1E(|)p#W^SF$S&#W+wGDZzy!SeYaXg8sbPqcupJ2Akji<^?r4Vk}K{YU! z=A2AnMeklcUjV+Ks9)41%F*>qwJ<%#%kEcPya4Kt?k1w!Bf+_wCya*Hg`v&Te0zZ3 z!D5?*M-_^+@8#LP!L&1bI@P5#4{<8GxE-PR9_u|0e&{5)8|TrD{}>_O<#N4tGPzav zS!3=}y!8Q+{k7bTQSiq=H=V)sug7amF|V&qmP39*&aa_%thExS*bXuoGMV#tr+I`? z!iB~%`+tFtgUikNh~(w?F(s=@2)7R5h|KJzTXtV~Kv29=p=Mx-;^W5t81{=u6f?Wk z=0_1xS-yHtM!i2KLwVUdWh{+6@(PQSr_zAAS-rvZ;s(nTd#&dcr@ACD6nh!-6$lUB zAeMcx#|e4mVIjMVHVIy})RFDwTseI`{fQ$RmP`9|{V0j%^iQd{iK3yu8F+=J_2 z0$+-AhAW-a`P}7rYB10rHC@s)B7a;`fBqstgDFFyyLYd-wV5_wg)(2*!|jDAy^Y~( z$pI`m0#rcWpu4u=b1!R^s`)hl+Z3#N;M%Bl9dFn4qY%bIMd!Dq%CEdJ5};SASF$=o zuhP{PbZrW=(rZPw|7})+HW3~^`^sR`V%@a4t1Qi#GG+KW>G&3WKvI4RGjzuTx0sIC zH}co{g-y1qmpnak0WBhFQLtH4&uh4Ie>p8lCU{bgQQuRF_#A~^25Pm|0iUt6sod9cn0oC zzH1ScO2p<=RI`qWz6u;yAjpbwn?*a2M>xyNBhj*gCUJ| z3OP&DwY$g6x~n~UrH?LV%1e0pLqVzf?H>V3Xa9;v=Tvz~zGFz>vB+muvng_MHlRKMy<|4?3p>AkQf;?7!2{;Bzt$*-J3X%tqtX{b%g5jp--QJ=z7?&Cb=w z_9FeNC+%cg!ttgWv#6M^%8KVH#)^2-7n|a(piP9XS zh|d@rE_9pJ4^zxUQ_UWuK#&U#&IL-gra%*PU?uGs}E_>q}T;N}t{^wcGMPVIQ7`Y?WJ_|X&PCFNc zzx|MKnPV;poFU2({rJwpPygJ*p-V5N z$x;=+&adJoAp_nwL2gZ&F1c8581zHbg+2Bv6b0$X$FbsnH2f`m6NiVi|K!0ry=+Vv zSW=)+w;1<4OxZfP0@1Ea|0unyJ!iK;c+(4v@N;1;(Y=*ev2;* zG%|8`7!3ZVfG)rg`z*!V;us0ZipUB96@Qn#-C5>TVQt28wsbxIeh;2_=()y+@PR;< zE#)YN=`;LL@Z#THs0c^XPe`^myswk+?i3|jRAiXq$n&>YamCUfnMH;Gc~0!{_)%t` z4*r-H@;IvlPc+ukv!VYtlJf$zV+^1jiwR_z6Kg*j2RIH%`g2o+-iWKl{74~%1o@vVwGIy@Yw{|HIpmZ zu=BR#Iiv$qB=6Jq={qE)CKkX6f32avx)i!7V+}RQ=aO37QX_R`+h+HwXcm}fyQ@6F zX|~SNL5`fpeL3n?LpqmKyfW8-KmR?gwsa3ri!oh;0KBap~mD;!wu3C65WnTQeL8Q1`wV89=9RpvgS;Tp;pb<{w z9WivPFXRWLt`Y=JYk%%K4&?ItgI1*w+Ihf&t`=s5I?qCahqxAY{J_vF)O?C@{=mQ_wy#rt|-ib258=R-*?$1`HtO}mFN*@!tvzg z=rvS_`T0=gw7+?=K2`Jg89=4$ZCM1(4o~GYkIG6hDyl^ZVj+8EU!k=$aa-z-z5S}H z{EMGUYb4Z=yoir(his-py#ev*57MbJxE`%Mhc{A|Vmx?bMz)%?i*1QmCS)yNa4sC% z&Dm8gN?#dNOv0b1zm>B@^?Nl4+;iiI^bKloIFJl#H9$s`Q`6ZW`XAC?rCZOJc!aXI zXuztuiQ*Pz+;R7uuJsv6IX=a5N^>t0VSvrWC@C1RU_1ho4+c@y61CP${qNlIM74w=YoNqO?${ z6n1vBebdnF^`4b!Ed=sFvvq=c%*~f2bN%bRiv%p6L@yqppfaNnh7tV8^HB!1 z98((DbvolPjUE9jGizhQjYfGMmUSbOZDoprKV2s} z*E~*lg@r}SbU-@K5i0fcj-l(@&TUX1SrebZ3&7FPjypOey>SuFhI^b1LchOdC7Q*o zC7KV!z=U%5=xCrOQ^7YU^KqNBY=O)+#M5Yy$T4TaDIfJ*sVmq0CELoGZf%V0yt%xa z@~lyy_rl_ctLR(fbU)uX*I#GR$U*fESACSal`Q&eu2>(n&xzTTIXOTCxCmzC|Tj%Mh1B<}Ucqj^WTU@Gue@G)*@2ht}LwC6i?`W|>X39n4({I>r` za8pJcGa*>Y+$QOv#`L9b+;N}VG0>vbr312~+`X5}-Y}5?Da#P#xxUD&2Tcs^j9wZq?C^IWDhuN-CTKl>eLou|twW$#p0_G& z7A;;AhZ8_mp`lw##z<>+xRI zG>gE?U;u6^y^z+KIM%*iff{%7;{N43*Jz`6{@&w7{TD-)=7E)qt|Fosn%d8FczqYQ z`@~1fZ?DTcIvIG(29-3r3sgdXkU>y(-Z^EAE+-KbNEB#! zJAZPn|HRIR21%3ro~HIR&p+3RACM0SaZWSiZkc3NLcflfo=T1i#*m75{JjX*n!B4w zdj2iPshpEAFB`CcIP;Rp0Aj-lq*mH0SMO89%;*Jxu?datJsY<#k=b#w1z`WuY2 zoT9zXYORWMQ$sB&hg8*{0T)!VD|8!%WiC_8bOlyD&Pt6t-=mqo9I2E$o~XJc`e$R8 z6)y%uwFI5##8Jx>AESE}>+HcqIaj2<)Yd>*6aTbJcZgi>=PsfEf=;%28$mV>z$K|7 z!ik@bT=GPWSH)b#t+LgKl0nK30oROha$fw6+;w$M)Jd_Uf&&4b{xwZ<(RF!W9|ncO!3>Isit<-7Okif}Su+9m^89Rd4;A-)Gd zkH?5c-=QJUa=@tbnuOjZg2~F0q+eHtn}Aswh=nDAtLR?p`MgwN&%wy%v2e!aTt`Ri zGI3pt5Dwx`F9$aN`=`t9?{fR^N0(!s%PmQ@sl5##aQrJ^w0XJb*K-^|5effu1J+W( zEt&vCk$31MBaUf92#kfkBN82LyHD(U)bPZB2B3Anc&VkaK`udNsOQmVNKp~zryB{I zeq*9Rt1^ROz`lpSG*FPnw_$dL)WwFm=VDR;CQ9fDg(bpFNG_)j@4(SrS@nNff zd)wOWWq~Zi(W0@Q4VrGW2W9Hc98js_KS+EoP*fq3=~wr|X=}}f$UqR8)7V?4HU@v? z@lwHVekiv>1geyJ4{n$}CZk1Y-?MLzF1m6P>%{$v#wjyn0w?hq;6fg|e=j1L1HWST z(`10?a-v!W-gxG^=&<4v6*n2~#jp5h{7L(~2|uZ3(IyWgp`|zP4>~iZwiZJvwjrK0 zy8(f|qC@=NlDrhGE7P=(&#Q`N7u=~3?`WSBRC;ZZ8vCk{+XxFs@cu!P*{D%;*G9y*G%WZ^Tjw~E8#A^K z4jl^gVf|4klBe}oO|#c@-%h8Rd@FsjXg*hDgwQIX5MmDa2^xmdch$n|=#1RGLd;B` z2VR6dHacW9MoOOTjfCu(i0TE_Zou)#pta#7;&{*y0Npg~S$UD~oLCB_7)*XJKpB&qiw*Ch}Z%@9xR{?c@9Pan1Xc z$x0^`bObSTE@^!>aksf-{@Ln_#PXFsKf1jh8i%g~2!a|{3l;9;3=da#p0@tIpDwrs zM*({3?n;Lbi((`66i*MJC@UpD5t-$sHP69qLuumiIoL-I_$bLFhT{Q0lBhvSV{ZVC z)Py-cfQoW-hTfu_Ld4KZeq#X6yS`5-B)x{;lnv4^RK+f8X-cl9DrY8U{<+KOjpg=3 zqZoGck>d%PuLXr8=8C?~d7ZS&i?|!ze+f**s>PA&Vna+}!Aw z{Zi^<7Lr#!4c$o+1X$9uY3Kuos{dbaZT$O^q)k-N(0EtVEhUzeQdt$08qx?Y>G^S@` zh~wJyv?&Kmz5$arJ*qWn+eSg^*-xLPjhWMH**o-M*@bO-=V|2L5IDlu zDL)WRI~?(DZ%Jm!Ey0U)C{)yxKKxZ-ohBeS@uqx}ix*&&27e$=tBji$ViUWLKN?j% z%!-!`(f^^zbeCVbyR&g-wfLK=7U6<^qwOZ83A(y6X9Z_s>or~HtC1J&->Y0BX8Yi| zIeNyF_f=5AJ(hL&)s(1}{-}eeHD(sGw;sp;baXDB{Hp{f7AdK;#S`|HTafNHER^?) zESbnG-4vGLiFy@0CZ(`Y`mNNtc;O$x2&M;jqIdHt*KjiXvD@`pUlXRz2GKx(-;*n- zzdB8V%uxcoDH9Y>|{deWn&C=Nge>q$6hsvUG)RN^Fm&K!zGs{WM+bpM_+c^RURPh-JMze}_;0py?S}cJQSrS89=Q{GCNVQ#T7_I+rF2sW zEsp9o(sCj#$7)B3v=zpm(GZZqh559}rpH!{-Q)z_SKccBzE<_BfN$Out{=BGg_L1o z@v(i2uYMxZBz-)^bEs0qwZ0berd(&;VnS{2m$^%Hy)0+sxxUG_&rhc#`4fqGLv(kp zB)_Z+b*>*fg4BQS^ZeP%KsQ4$>nzl10?hbMDuZ&xhO?}*C^&&54I_re61@zf?pQ{&%VQ7`0U|PZ}nU_;dx7kpw#O54ymfM2^bB07^-^ z1QyxFMc9c#@9yc?rGcMZKJIJ5hx8whhmW1+ni)FYv9<}k8ZdIeFUx75Bv4iX(E&6C zwB{54hsmhi6ip2!hN)e?ZEf=Z>I9W*hy>9R$e%_)A%Uy-pN+cCvg!8XPuf^_@bn-d ztN_H#0|4YQX`b-4qmXJ60Cb*ANLGtZnR(Sot6ALFBlqsZU z2Dm;VANcaLfQFF;<(%!yaZwyADP}QfC;&I_Zrohrnn-ZUSJ*|CAUdfElsaxEeNR2W7U5&Nvo_II2Zt;D6;M) z`F;)%{PHuJ~WvfoJ7?QtI0vlUAr{Dw$JezNPphC$4BCQ<1VyoDcamnq4n-uld##u$%s%;(^6 z#qLe@uA=*Oez-)c=~H(WYsenqKZ01;`Vk|pW=Ficf#40Zt?L+(-PXsht1 zh|`aF$l_-E`L&|j0f*iD*#-LIWQr9FU5`K58oS%f^{-xIMRHR(-kD!kAZC)%wThbT8JL4@x-#FGVa=En6UQt<0-5Us8tQH^ z&wMj07fQk!?HNg1M>Y)=5G&POu{%?e_C2Oqr2cP&AaXe~f0-`tNaIJv9Wfue za?!?<+y2ElQhg|kQ%AFgUQf5!FgLXqo~n==846|qJDL9F=|2ob4_vfhd; zLkMFpL$dE<-y*UMA<0?{Ny}tkGZNW%$-Yh{BoSjt*6i7{FSFdg_vm?^@9z)y>u!8} z=ChvnIoEZa>!4R_>_3Zry1;38qs&zy}G#rB;*;`CdF<+-iQAxNaaglypIM$pPD zHIC7qu*L$YSRb_3u&h`aMh{iIWh2}{Pj1s8td}c@0FHh+$@l-^&k}ax&CA`?70&2_ zD~L}GsWLIA4zxrbskvoi)-DQXg)Ad5VdAJyLzwGV)g#}-a7*G6~k%Ku|Ab~4&Z=gCQkZAT7oI9oxnZTd^ObasoU zcl}oTF$*)*^^Gac(Z2Jw26t%YxdUYSm#;p5q`XW#L@6$k$EXZgCT}*qZi{{oIwag1 zIp{W+Y#Qq(!l{UN=#R|lr|N-v3*@MOYNz%t@*eE+x@j$p6Bk$X;ERNg$8zGMDJPd7 zyyLn#XmL>Yb?Wd0XqIar6p??ICu-ldnyA>v{~{ZI7ESk_K4SEkhNVNIvB&NQmHqCQag7POz?EkFVQE_$=eu#EPfn^@ zu%qD4WGX+v$hyplYT<=nUJ|c<_SqeG@2Y&M_l7IF_nzb3TIu@IoOk=B(a6O$i+tye zbFfasRK%=l@)IOkM8{eu?i`qe23hUbHt6hX3{%uUg&5h-@$lMyMK;3B&+>nXB{x)n z0f`z>h`u|98>Nd|F_N~QU^hp)_o-uv56pztBY1gxZ2sYP+M8+t_}OjV*F&)!L@5s^ zRRJEJrgT5zTyC9+p!1j)4%D&b+vwkI#zJ3*1n{wI9Ag1fDdxZ?9`jVSGN;ledul=x zamX}qO)Yj!0Wo3N?;gSsATWUTA2r!nG9#*}xhHyheF)XX6o+VhYqU0y9jN7r#69!! z9jh-qI}m8(ZBq@@NWP%gk=2$o_|#%*jaX%O;mIG)dF}ZpkWjAZ`)$gm4_jEksOy|8 zEh?FY>EVAKVa8#YTcJ(rju3^T;o-1T*VZU@(CHEfrtb&>JeE$TO@`Y3WS#8lM~JNk zXY!WBBHxf0;4*(igZCZu(x|fKP5&u@rnmk{84111tUxWi>_5;#?5?S8F4qW|lP{(l zTF~#_Pcwk*+mmbjq$b8>K8sWk+P50yJAIdKUg+<3;?$Y{Nu6njYoNd0^3cS6Uci@g zRAK1UnrC5!5Lrc@{9wW-Vk&j#1wZ2P;?eNHxQ*D8>AmuiSC5ToKI=e$lgvuypw%t% ztcU9YuVJI`Z$XRMIS`=ChZ2+iWOVlIJAq3QkF9K&T^0@K{yBYUjGND^C*ASYQT(FZ zEqU1`z~Ae>;YyD(>`r9=tY;L9@sIU*W6)@2ZHu{^bWTZW-FrQfSf85{Qn626F_&G?Z>5o)j$3>(RsPXp4v(~1;FK zUI7cvTa%bn1~H7H-P0xATWVXczBvV$g?wOHG;GExq_8KOslnB}Y21Mmu!x=WC@h&Z z6149m3bRE=d>?*k={Zhy7)vno(C-|LPd||3B|aT8HCq#t170Dk!1rbrXy>n-Eh}+9 zMbq(ezxEDU@*Qt)!!|zx$4*>vHGiMtFU?nEdTWC;(zS#s9o6ss5!iqFQ`@t}`I$6f z?C7EO(AwC>*-kAiU_l}O?$8WX<7)~|_ z;kr5U&RD;CJ{Bie*n>jVO89J7-43{O`d^4B>^o4I`pXvD-?lrU=@ouTg1AL#)uIlE z?xt5aq|n6@%E6c!mU*ir;02yE^5hsJ784MIXnVt+2F~BI;^LQiJ1 zp1qV0wFWi#C5cpL)rb2OO!_k-IHSzcX@FpqOXBFjo^%55q^Vx;vmKRe-#kZcc#9pd zugFx(7?@#leQ{#cR-ie#$?b<1hk#a6?Zn%9B53`V#8599qkPU9i~AQj=GM|rnDo-# zahIj;GFhBz4wL>7U}Bcj;P+zM@li``?0$NSyGL2eCGR8m*{zxAj&CN~I&N926c`fJ zmfBu&wtxq-Goc_MOnn18Km0FT5N@>^dnae#tQ726owvo7L&)Kh7pLD0Hnp&Lqu$cG z*85F$fBL=0sc-&=X{}xj8#hLHq7P=O9|q2ECI7_C)d?l{ICY;A3=qF6h5pC=Ay*}o zg>_xzW9+pZ;J(lrQroI4*Mp<~6YVyx*HvO}9_@1vLx|Ve1Ko$H;*V6STFlh#nr*S2Fn|kfglKSNSHp`Cn_k?9D zOC_ZTzvX$p@0MI0uK-JX;LkYLFmz)j_5{XP!x*!+w@~uMA6SQKc--H28p$m#W{+bb z5fHPMF?p!~yE{+6sQ%Q=_UChlD`gFJQk&%NGx`G2&qlBIfF<;_;v37@C5zbyhS!Av z@`1m)SkQB6p{i%)3SoBiDiPhtc>}Sd_)pmC3;uUjd5lrx$txQ;qDWLFu^rtgGGEs9 z0v|GUk7d(lOcBOvyb&mq5OiE+&Kks@faHfj+B*;YHbu2OJ9;`Swd6Kb+&m;MqG1BdsbI- z(wT$rPFvk36WNcKEp)f;qx%?c{&|nl$AU_}%%-N%*U&XW%cfqu+9kWGz)0c<<4D3# zUH1ij{JHCh`Byz!->Q*Q0h!yFI8o1uI^s@AWsteS^WLWV@3R+W9Az;#UknUii}C5T zY1q&2tIg_dgWy)o;ZL4%9aC{18!uqptq2fEMu8dci0*c^%fM)@K1$Z}* z=WGxYfJZp-F}EO5e<6%j#_IIXy)Qp!WgO!~DthV`b~gY9k)II86`SsBQkdUIrG>e$ zj_+4tzUXy`dzys5=-Jz|(k=$!&nVH4ekr~Y?88+Ek?5w#M`0(kPTsdFI?QdSU+<&B zqLkdeSfiYXa7gojk0wC5k*_H;tBejq=fTZ-KfTme6*yAz_{;ex~_&W zgaBluSl~gjtOKOOKHyl72@Yc*AO^TYHfR|753d3I4voO|0o2Jc)IuRrko_vO9F)eX zW5Dx&%GJLgP(D2V0pd*xZgFhTM;Vq51}y@7GzkeX6^e197&OU95@hcu{@V>jONq?j z(`twh1*kdxeqj4SOW6nbVXp_XV6a{w)2Odr7N+{i+tw}sHM(Tre*2++riiVMa_oUA z)JUpxOai^Q?oC)7d{H=A(7pEzaZBH{z=--z-DE+VsG6cqdcdVG-*r5pS0!4j0y{;a z*CB-U>mke{9&#S!_w0uKQ%Bgh>H=9cBHEye!$tbqcTg1AdLdCjR$@CsXm44%s&L4B$WqWUy{-E-fZ={|O zj@iPoI_*oGS?&AT6~mau7JF^o`j;Otf_uwT(f6|ymAfu5)%?(9H)z#-oi9_^V zT&yh3a5ZOHvO^#&G|?kU8E9vmm43obyuy%ac;f)b)F}mpc5W;_rJ}YB@_9 zBy_f2`cmGeha)^-BFIW{pB)>ne;_k-;7z`s599~v-!ip|*!jifGg7<12R*n_y?Y}H z>e#BXh{LXnjw|tx%bPH z1obATDw+c)qQ@H<+)Rg9kXPm>{>z~Va`DF;THIZu4410Ne z;KxJsOSVo-{AEAS{wARTOz{qzz0kN%a!d)b&+`rSUibV}9{NiqsR{TQi5Ax6-K}1c z-KPZ)nFqbE4_2^WJToD?ZO74qpVxom*YsH<6CWJl)gTocYYXr~(xrcj1#;axOB=!BsTox(NAYNmt>u zB7sKrO5ZI7ne&xp`UQ5EZwUC^Gdyj&d0=))noj?pUFdopI+f6zId2ui*kEqXR1i1L zxsa}|4&ZSt~Z&*ZJB~}^yG6ApmsgU*Ers-L768fj@Am@Bf z#`vEex2^?;XQS!54+qIS{A*Kko8mCZYV1tux4%0Ilz$}24%d8qJmQ*8wILHQhG~LsS@x13t?DD z1OJG-TDYkWk)H-wv2Yd*i0Vm>VN3&w-V=$j!Jbga8MC61JT4CZI%eP^kbfU127$GM zWs3q}Q^BXz!d2)rH%)R?qPJ=-D)W&~mHYwrehjE%g{df0ZO^BqAFmG8CxvtPz!9qE z<2R2neijYS@{)ZUuv{`&pE~c@Gx>jK2kchBnMs1pC;|k8_*5`VxGRgc%ba;h=U2$a zhOa6gW$&O%>^$g~IqsZ2kqykb7>&1Tmw}kUzIpHo7(UtXkki6(tr3U_qVRoG8v5dN zqdIh;J*DU*SAfw8Q_AH4JOVXxQysLlGDG?S8V~Hr1%R-_S`Q=<>SC1NgF^=W!ZZhk z0F*)kX0R)_fU2R8syb;4EEdNq0pJxZOr@Qh2d3Pd?%~MIfkPS!yb6E!KoEX#tS6+8 zCR~P(b)jH5#~Oi296UV?(28@sgaE{FgVIxF6zBmALEfw+NaT9*E?V`rw|cwJwDl(m zNJz~M@GfATT9;$}1U;(5eN}R^U(xC7+_A&?*4&UbydOo#u@zS|qS1!Z<>g}`_Z7^? z%P_~IUlyDw$F4s(7oS`w>X@#LbhRGqCu624%3?5#PlXn-hdTL(tM!~FgsmF{i)qjC;a8&P9T|o4M!k(Xo zhWrGE%!>OFNcekWC z8JKAQh}yKQp3Z2hGm_5dtY)dY|Lzyf4{lKw&?rzzW5XxjUq@;UiYoKvP$~-G3^>=9 zGBcz7sye1qNM3o|RDdNZmME_EPcxF!aQba+hsW<9MR)781vfH`SPZxj!-W&|4~u?= zZeT}xuK6tL=2~i!ZiM( zIfb8Y$NSEG{&q4X&;KotY{taHp{5Dh9*0c#OzFGzhn?M#vyU}(76R@%Os&QrZkk^n z6zBamA?kUrji%sRJ$%3^INid7HfGNhfHtXEY1|3%;aN6UWRk6$Nn;2;YH|wR+OSvd zzOb&FLRxWM6kFTA?`|y9ZNu)QAz7_{U-91O0e#rH^{<~RMhzyF-G8q$mPhk>5lZL~ zCbs=Xh0*-0jtw*|*7f!2t3K^blJ&PV2@32al>H>f%|4cI%An;485}-ft=O4=e!Tgk zPiAK~TMw=qNQ(W-I|~(mzOu=TPeOl4Gu$Z#1E-#Nj+<^A{xF=LV?Gg0>YCwAasVL7 zeBbVoh2h(bS_>xJ!?jaKH$+rV&72GEJSDOJmiJ%MBp&Xn`&zsf!QYE$;(J=6h6)0O);_MACAhsCceloswv|+Q%8D zNRpNR7gF`s`&CKl&rZTuFiLVomVvq7EtOa4+-dr+vJk~1Y{Bioenp`_m5{}PD?owy zU~AGwr?S>pa7$h<#)am{?54L#>cA>?eGfkNir79?mr+vB`1|d^@MOo(j{_{Vp+R(} z^&5t=47}M$^cKw)IKfh$Z7Yk>BFij{5TS&X`@sxWTgzLGTCLG&tZECZb2ZT3oktz! zA*kInJ>B4KK^QJa#}#8on2Vaw!J53Opr^s#v*5~W>B8rkdjZtwen>j-e>O_B+6m z?Hck>ZYB`RY#t`kY6H&{9L+Wi#uf_YdHgpA?uN~ zhpyZ)oLByZD0bqK#U;uG^v7 zS@zh9fwI!Uo)`dE)4u4cK-65(*3EoHLY;;&00PEo4$^SRDj}|SZMm~Rrw?Ba8p*YlSH3iV^JLF#on;o7zKRZn8$|x2VK2sa;2IAMu~xpvHhM+> zy!SEOo3Qj^ZNnAk#x5hQH6&xTVFw_wF*4+8Z<_r1# zMd-zgWX_*;r$|xJ1Gnpi$cMMF9VPd=t^kbRd-n@~VOn3Y>fX+7Flk!f2OZ15Pe&8a zx{{9oSrlnwBQGHJ^u@If|3kv|C7R5vQe8rq0BXjr=%0-%k+bvWcUgvGvYlD?V}}zk z!e@|pWFNQ@zzE|t;%F)pntWMpfp-I#wF#f_T>d3i{#`o^=!_$58mE_WJ43N^C6=aB zpPsNec9IdRxRrXu!BWwcQtYCDex=%k;$EbN@jN?58Wao)0K9=PmAd77yC1_PD_2Ph#k(H*@Oyr>wH zv>^y0WCaUds%88b?z0jKal=(bduJMC-~%;nUWprCVwvUiJB9l4u(2l3lk{WaE8X@- ztC>e<%9!=$#nQ=X=+z()Cgtaf=h>> z5G;R5@%lOuE!zKHEOV!ijLEKA>m6IMKU$9fwJ%#qNmwaj^a?tzw8?oQ$Qyu&ePlft z?g`qhrD(Itp@q+wZ=t(6g}f8ifPd(k>T$Cwd}$k8Mx4d;a@XDBq9;%L9%|@cRLkp(2M6L0 z=RH_=Z&h}03eARnmG}eR``$dfH5?_;$YaV?Y7N9t}!@0Dw2l*=~`X9>1`W-1g)yovkf7V-^<;2^rttQ)TBQm zV77IyCTXX}2yJZPN55@OPu>C2?i*~n2hRqv5C$dQ-%|x_MM|;n)K|^Wo8w@C{pz~~ zMr`f2yXk5Eykoeo#WGinC_Ab5HUX@Qcbg023|f?3xF6Pv3SK;KiC%fn(i3^BL8H6y zu<2Fbl1ofdx{4t2{WB3Ij%1A;%LU2S@%w_R$EB!+6wgqm#v{%SR!! zf+)8SSvP#N^u^%uDjnP=20+O3tLzdN4im=olu-Q|`KM$b)x4fXjXfAMoJm(XD`*zm zt=nx9Ee4Uxs16&b(vDX-r4MIShfvj-6jd8RP`(;+6g4m?0I1-PlK^A}gZXH=Q3>Y& z&>f7W0(g)Z6p}O%n{L!l)@SDQk*9kT59ftU`UR9jsiqt;m5!rw2asI;xEA3X zxnKVHZb&kqZ%ZLJzH&|GJ(kT}kIj>P9l9n5X@@jP{l24UqwF$@eSA8c?RxWfXyIlpJ9mVxAC)c`X7Dw4 zcg0wEbSk)J!6ddYxqoyiK*G-@p}WpsYj&)~m!i;pky9m-<9UmoX2s?WFE9gim^~P+ zyrvpClmW_ii_~Y@7S3OOS7)97#2w5^0-bXwJ*_vq_n(m;ik9`y*LH5$^y11~0-p|BR?OA6c_zMH8*zN^W1&f}ktcIWLAvZ;$dhM=WB~vMd~F}D zm~Ktsy_7aYb@{#LwY}n$(MS6YmdgId2}(n*nivz-5(avs;2-K&WJK=o%iT!4>nV>! z7EG3RsQw7_=Ka}5+O}-H+_~2V;8JNDWzNnKL&ENh8Qw!?!zMxrSZpv`g$27Q9ukop zf*5PjA5v#PXKc9_?@z;>^58}Zro|qhb_9cyIEaFFi07^^rT1QX=b)#q0eRy;AdiYI z2}OXws`F9(O8y&`11;piQ^!&@lvtbR3(KQ7gDb-4XSS65?*>Ij{V?>r+jvd?O8G~v zw)pRx+$I(FKaXN08=`LmaQ4e^V0!n)lFigeiYrs`%6Bh!j+!!Avk`oeEpVmK>H=hB zkqlS9t8-(9vQzZ?Gl&cy>lQR$1=MqDg>FDr`<(WZj_FG@p1u!nR800LYTrq#>lXbo z(qW&d*Avi}U8MP~SN~l;)><_82IV~jEG+2klZ#9W$@fk@P&eL`=N+Be`^M|#z7hHT zNH23u98qSzc?(h9k6X$(%iYKxm;)4mF%fOSPh|055*xEyPfmQ;S+T~pM87FcpYaPy za=3P%<;xG~y&k+oloqTEzk&<3 z2nFLJ^o}wAS70KNt`_w%)=!B^!uiLs&0za9J{`>oprOCP5ZnlmwSmSBT>vJ5P;~+N zioAObiRe)Q4Ko?_o`-H!Kz`UqJrk8u#KU;eg;4Oea9f2Q2qBq)HWoCRP=X($Z9m4q zjmm8y9CTR(Adiu%QCpz#1o#y|kbt{}FlB~QKjpTAZ==$LMr91Cw$)_K$Py*X|va z2AvrSd6c~Z>;jSleBS$2K4mnojp?_uXVK=iLw!}~U~cV~Kv+(M0(*DrbRA|fh=2eL zG@O7)tHPdl5s5tKMg>FN1I8l2RqkmRm1=fo)!bAQZdQe<;G)=mh_tqfV_Ab6L?ItP z2MC@Ul(28$t}Wa6%wF%TUb~JFF9d|?-S6(Cr!j=r(heXkv=#tbfz4GY_K`%XW&ym=N~{I(IKK#9(CFpaCuh?=`h z00yU)1IrHZY17N1NAk9S1(FU1d|(&Cm;gwYMX%A$ExW+wJ5X`Wf)#idVQCtWvSX>EsxBq(sob?yyd|9mPEB*1h7XHxG_aL z>!V8^5@cqFL&{nDtu`Du#s5jPbyfB%eP}Q?7U+qY_lqsl@4rGv_G%J_m?hwl`Ye;&_)MJoKlOVQQ>T!W`IW8QRVF8YnXl`zJ}%@{B6%yEBy29+%X^>qXbyM8EG9!Y zsJ>%_5QpiSc+JJew~eVaq(9IzbtM#FV`4Y6bEz|%J;&-c^O4~y%y5(Ex$O{1fdpM5Nv^1|rPu`+RbH0H_r1@h zu}%I9^oiu((6NkL+Ic~SOnJ{cTR)OSVRXy98=R<-0B4e}k;hMM?`et0=*F=?k|<(B zZdN5P%g|U=WGvaY?nfT#*784oSexPs=CfZ`wmRsyOWQIAT@w1}FHWdhQvnM{mn?d| z6fkBjq!`vPp+YMGf1DBqMPfXa=)z>-FJ_*K=AjSW96_cXBH80Ip-f0q29qek4YZ5LW_L(oIISo3#?D<%0Byf*FiVeep0IR&V}!jwuwi> zVxK!u0d>40;jzxt3EGopqu)Bc6bTNd4|X6W!QR9tp6C@ynPP@4M@7g1WyS6gdPgJ$ z{-7t^j|)&4k%)B3a-<9MwQtQu@z05t*dIe)lb5_IYo(by4<$=4ne7?N)mIy^eb!ePjMwmPWh3tdqE11?(|2c z04nW*TcnKM=>{8zkBjqM-?v3Aehm#@p*KvWDUG;xXAkN{+x_72*Ws(*iasS6YJA!) zN9)~_ATG|EUl1bAhG!1HEJ;a=uaoQMtWchCZ+7*b$FSd8RM|6XHYmk4KXHg3N_L{* zO)KSxKL5yJ6TpkFUfXc8O!SpZWU?PvaGu>_^YasyqnoI#N-zL^dBMSqa`cX^Y57lL zlwJgQIdake3}>^jin~5&b#+{8sQU-9SOMK* z9rOfq&w&XjV5cz&BgxHm==BSTL*`?7-Hs&&X08}II4-?ES)*%#cp#m4 zprP;PF59!8n5=HRvF~g7v%`MjkUy23yse=^_Ums~?55FA=F*J`JT&vcsyM`%=ha5$ zC(D-bl;to}gfr=q{buRrzUFYnc!OD>Me;Vo zm!)bECUOmvx%35+Wk&;yr@% z9iDl{E5KG-g`u$0R1LN<8Z;8&5~*cR2!X8aZ&s z?)S<{xYpUSBITVZ0HWMJyvml&x&B6myi>{2Rb?U0E1MZt=_(C4_FOV-+oV$nI$k4Bzn z?gy9&^KVOB?l+hNC}JvW@GXV=$`|zU3b*{*Zuua3TKkLz_tF z*?shCMZu4qQc{y8iS|S?0cSWTOx-i|A?dEk)?pMnjtw})KdP#GC^0EiQ6m`Y4$%qt zGbp}@?Z@<3^R>6$WkOF~1TPXK_kOo=Cx@*x`fQ1bu(pnbgUFTWHWHTMbWjdfKIfp2 zJu8wh*r$e!<3LpwnH{#cQFUOhq7qU}ue4U5Oo%g;temLww|u==W2o{u3uK5K@U(ng zoa>j7g=A%0i5iIT_0VdQB4H{8ck39gP?THNLKwTned1&_m8#JCKq1v@ z&=3uOK2}IIl8~Mah6+QxmL$=%K36^qf`v7JWcM@-l^@2aMu886pw;-}f*z8aN9i{NiFN{o$pncs zXv_ZFi3qIe{%(>@0Rbq#0j2(l<9{5hawyyXZFxIYhFiD=zwGy(45s25Cg=@|HCi-zg(NLoKRAIu)aVPDRVw3fQ0b4>#8^T>yK;b zVV3>K2PTh(y?4s*8@3$aoivv6@t`aJ2#Gv%jG0hK(qm2-r1do1%gTRYJX`tIxNhplt9KS$jXN|w5}N#7z?R%|=U zHTP-;Bt+|h3Ydyb3;vQ^Zf>|Am^+SsQMDe7&w0A%$4!Vq*6+v+9ymwXXyMwMWV&2l zCw$G6(pe&Ju=)KaSZ=KfH*wtpQs21e&fdQkf5gDB8u`OfW{JUX>Q}5Jt|YV`+U0ti z&*AAs_ubEPD7v!_K3dFbYzy*udN>;gf=7kbY};OXXvmb=Ohcfb=!nx!)@GWXm@&uWMhX3cYIdzz{7v=)J9|hQ$)r0GaA&WgfL}lfCKm>}9OeHDs>XUIe+t z!TOfIv-klobCmCwGEn5#u*|q2Hm1N7xa?{l?y05`kEGw#1j9fJ6`Ws}1l27*{tgZi?KdbXSh!IqS@`I>Z_|8W zY#z$(=+UtF8oxyERh443c9wr3%0RY-MjQ>|{v;8nnya`Tu06v3Dy%el8J_K<-V$Jl z-F+)5P724_`q=hNd-iJ-I zr+(9J_kZgp>A{m{?rj1I4_&qR?#q%UNpI1cK^&K^j)%%*Xx~aI>M-BpTa}aBFYKX# znm<0D5Y-O^d(gj{i#%vjc9^0!lhc|M8a%MW#cxFH8nKUlPOy{Yiyle)LM_@a-}Sa- zbj3{EI-)cG7n0(-vR@c$l&Z!U4&L!owT%zz+#khQo=(=rYvl#znQNZ`ZkyE)dJJ?g zgcP;df-xy8Hs1@zJeVW`4n0MfB0kQ>>ZmE4O)igU+pj8}k&v4YecQn1@S9;jbjbSv zhxnRKN)voF<*uEjbUJ9M)7}5vdzK4SjT3djVM==o#ev>pkNioij4y45at6(141Xys zT;u&NW1-(lV8-jo`7J`PtD^XAI&L1;V#>DO2~9S9psw-zF}yN!^6f)&r@2}==!eCM z;9h0!Ci`jcPTpDliExe2p}UAlwn2}2a(jjiIcT4Ruj_clX(?3&HgsVlYr zD4QtIx@vpq@M^5$>xcb~n-5qO9vRm@@d3-L&W8R}z%~4cv+q`ayj@3zvxiKA&X@A? zlZzEwrFIXsFvBd>qt6(lUr^oCybdc<{p|n%fG~<4gO(C4|HioNFjmmjNWmtM00-3@ zpaM3W$0#iI;Ga+UB4^v#cPnN~A19RW_!}t3R8t9jb`(0*w9v^a&4mrxDma!>RKsO|7sWC3|+g^ zuktu0A#Nf3C9tJ1pbKaI3j%{M?f4qFd#Y1kfIEWY0&oqp;4#Jc{IJ+oIZj0=UFCP>C+Ys`a?ejOjxPXlgeTv8J0l2}#RIb2R@ zh3*aK&=YsF77q%kw8pd})P)gZ)U0$-oDA@^@g_H_srGGToUjz#bAE|$&z^16;nT2m z3a3XIa&v*4mI=&bU7Hev0G-TVc!L`sWkiEg$xbq&KC6wj#a<2F1yD#XG77AZQYlf! z5db>^>YRDhhx55PKGqN)=vT0j8zehI2jUJ zp-jYv+s*}spzg*bI zSH3p#@w*P>Ik-bAZdCWoF=-zxBcw>1@du`Gh$9B3p#VCEyT-KRwG##*)zy>!1NCD~ zK;a~?9=>o-(3dzyJpXjbW39%_S8EgHw%SlRKjz z1!xB_eikDm*0K`k5l|F6fe?e3^Ci4S2~$bxY5>#V`s@sh9^fx#qL6VG8^K1@CbKW{ z?!}i|J%^lb#?y&>Y&q?2e9126<@=ioUw0>dz^PaZO%2nPnga4o#yy?%vu+?BF|{7Gki#batNXyz z0gxm*)NB4O9g0XJny?8i)x4-RcME<$&~7Z84`Ihs06Pts5#VLwpdYb1Mml}e{n|a(CF{L*vrf=O;a__lg0pm^5W*MyD{=kGv( z-EnJh-imWvVp8`3^T9UBL-F-`?^s$B1aX>Hw&=Z4wXv?&?Z2D}B_{%;PIW^*Wx6`> z{yCnjekx%Qq%f51OI71P`IS?GhS{MF$h2=|EOa&b?_b*ow0E?o3LHY3PxP)uq~)6w z<%eD1Dh^zHppRL-aKhoiA~wvVkow1%%ealdoU8o4Bf9Kr?`ovgtMxem&4OCPIsy(J zx><)(8&V3uIjE5^AjuP~Ps`7k_gcsXIOE9#`ZMF25_Zu|Jc=$agrtKW;vykrKc0)m zjnPjPlaOHdHvWu+^n-hJ*XNMvWH+=M|0?K^@K2l~TLT4(GfT5u)+sqTL#a==apTPW zNKMcA_InAq3A4KaJ2X)P3MAnyS()=km&ZA5%UMi02*rpNm6n&^$GPS&$A;v^1*2b^ zI}5|9iWXJy)J>=Dh3*G;Wp1D|@x`}#xO=z+ry6?Yc>~`h+k>dLmwScKc-s>AycS?m zwu~?5{Dh)svxdN2uPg>##*M~EuJtAeiXo3DeVmiVv8P+SuVml$JaNv+?7f8;sjqVz zu+HMj#=7C(@#%xiXC>B|JN5IP@ve5LD?W64tSto-DINdkwNFe9mSMyqz!9MgYyVlb zi>QFJ+~`mBxc~&%1AMzh;%!1vf@a=8psnTbFb}Ez#SfAK-RoKw7-CUI9H@7A~kjtWX76`0RgH|g#NksPd>n4Nsyce5$L_07%^uw#HD!Ez~!f#@;H z;%5Mce*@*Kje*GLbDMlQbeC&~utTTzQEp$d=pYw1z;BRwh5^;I|7QA96qBL6CQhsPVr5w*4`ShAttM4%mR>2LgDTbXDk3Cksrp;U5fy zvp5l>xySS>tspJX+dCddG#G3U;F|wsRvEMn03)3JpMvPPIs)%Fg^~c}&;Qj#puVAO z^_LK(kfM|#iK5OpW=g^0dHg3}HF7(yvREng&M6JyJlvrW#l?CtsNA%xxU+*xtkfS%PISP zf(V15pM=1GvV~Fv9m_>2gz~538jn)nf%8qGP|N@M<*}wW%J`Udp@D;aLn%MiVIWsX z1VA>Ev^ofUe-jpK7)W{&LB)3LnRUD!*bUXO8dZ&r&}?LtzTom5$ZGxySOrVl&=0+u z9Gc$9d{++@X@OEb@=z?8B-|}n(Uol|(m#vQjTC94-*-Y}xc2MOz-d6H)q*P0ztj2E zGBd#Va!}dXnU{b!PSrKp`BEO568V7caP!(KPA19z568(;?cD8x1ao!$wb!TJ6=CBv znESG$p3tzV0hxZ3_gtfb?Hu$YqD-)|^kaz2?H8E~{Fib*&c3M$Pc+Ce<$3{DI7-Tv zbX;Q|p9go1tiw;U=Yl19 zkjYa5KI#L9jGMei!Bn$uydLn?(VhTxzL>x@Ved4w2%Qv|R%!AaIu33d5`U+UdI1c< zy~w31@Fy6(J|7i2b#Zlg5%>rTNlA^JF8m1n@(>-P%8e4Ze#pw@G0f?3D(hU_8~+fre&}UQN;oxi1AzG zk2-s6h$;z%cLML3g8)Y^+%b;!ii0%Lh#7L_Wld2H?A{j(@6Z}H2z#Cx)0kWSw#w;y zY?v~EOLSlgX}9duhL4uUsQ#2Vpb)8j3_bwr2xOVY7#-gx#YmUlkKtIzsVWgsG-M_m zqX%-97tkc+9EFX^ay0o96dpdRfsn1fv5IwKFB<8_MGu%HU6kx%stIq;r3$~y!R-6A^qZaRF zCZ#~dK;{iDpIx9pLy2@@7lg2$^1#>!a?%>bDs) zPvDg2Xskm8)FoL?e$Yby8fu}G{^3hk?j~rGcFEZ#rr)Crb_xrrwyt`UYosu=5NK9^ zcw_QMYlt2o?lM8X1ztWnP&{BD%DZBMniE-%ftmz#jzM38jxk1!Q5|V@aQ$;+L^QZI zOsGYSbu66N_VY0(gnM9}fACCz*rJE~s%tG@0M$mdv4JX3%?lUVh2EH&kl}#{!hAHL zMi6Om-N9T0S|Glx2Em#Z3IU3o<-ekqyzE3kz6$642YsUCW5?X@F}-1|3*Ja|kOUg5 zQ-dY|H+Cf6G3mJMyX2z^r2+kI6edIk1a2^>i>C27H>6HNA{Qtv18!6&^FTlV+;a{! zV4>kD6NYqAXc1b7I9MuN!p?`Qi_tLQDLcI6wt!Kfv|3a{#u>qws?0wH7&@W6%V`Bj z?g1)3`ivm~xMPNvs&*|{eXIeKX=}nhfb|Cr3=}ORo+_7ltZ0ZSfoGb{7db$6A4bKz zkK$Ewqw(%mIh}P@HOmO%L)6!fZ<^27;lL?sC8sLkp7fn~a^BrqTBQd91Fo{@7M1Ut z$a82+7&pXhOj`>u$nZE^td4Q!OuklAdC^IDD7Qz_4xr$VjP?FnT zS@b5{=ko-yT>gNzW&nv4hzOjIZ?GALinzP5%vCUg_)=6CZG0v?SU zQFSc4tWAlmujuyh`iF6D)Sw!!;G|7r5SUjCS+o%RqaFhe&|bptd6UMgNDHvmOrW_S zd|M3K#XxAPRAD)R#Hc7+2O#{zm>4Csv4~%$5ad~de84kPVmPR=;PZu4p}S)2U~Pv} z)+}v|?QvHkh?4-1{JZ9X1wa7AL-2vn-v_{09Td06&)@NC*$*B>%HJL@3t+dDh0s`C z4EzytlLBV;{M`+u-SNKw=JBuPK|RhQrcWs;z-kW8X6A{Kt=z3(lU#>hD~o>yAz%NO zE*y_E*Etqe{Vy*#{XflBfeC8x?*j?GnwA4Sh`<9RXx4teBrBbKJ#)!+vv-=jtJPnR zf_0>;Jjn(g6JVWBVmi)EC}Ij=Qzb%9JJ%D$jTATQWxlzPb6%z>vo^}Yl@#mpRZjhl z5+3ac66f!1fCj*I)VJdFS~YwE;f{@C8PxqV{;`idW0YdQHZ;9-t!ubiCAt}>X*k>n zbG&4ff)$-fq^qzVO)I!b-dw2bd{%~NksuMlARp7g_8X}kGUt0W!K>Z){Xo-UVn5xx zYMWTXZ;ltJw3o5Eh43o5Dfys4;<dey;$s(6icIU7!M3J?^AIqb!A^5XG z2=c#C1#S4c&8tVVM32ms2e?<|=DyYDF>mv1t;F{<0)Y@((cI6Qp(FH8B)F}Xv|v&+ z#JVYeL}q6};O?W`p|jYLKcr7>foADkKRB*m_u$-4LbcwQNdyM!cSj!-R(!4h!hdMS zx!i2X^gget*xBMDcE0%PP=*%F51O1S0Ig2OYf*q{@biI^o`Jp{kj{cHIo8DGg2E7l zl)oCf2mNUyZ-HCU{WtsZ`;N$VgBC z=Rlvq0jT2(Bq`8(u#enm4)XFsPTuLRj4})aJ2U?I?NAkIbHe?s#=_!)cX}B(K9D6d zfiXDu-Keg*<(&Y9H7%G%2#2J>8*)H8QlA5VmDdgtM>T-sx(Ccj9VvZH;7z3*Lp9K- zfQ23k@ul?sUQj9m=SeNxBMyeu&}0lYsS79pG(Z5dmJ9M3p2t%%f^J=T@_>RdLN$YL z&Q4kYNeT#(s_oPup#!I-ngeG-GWNxMoe~qAt@GOW^t!ak&hFtoO>2mLdyz0S2|~o5 zgMlxntkdT)YU&V>@V{f!A~awb%K zu77_W)6+Z-6kFM$ZlkpmQIK)QGzro09b5E(Z# zMuXr$vKAc1rNc$&){R#|4np`%iWNhbk27_eltVYQ+JuBKwh=Gp4FG)2XGf^eBuvQ& z&_FpMa&nupD43C#XEnDGjjs;F1V|vYFPV3Y-bR*f`>4Q|*lXEvPk>-EH!n9I!eXt5 zNxJy6F?%NN6xOim&{zYsd)ZI#0Q>TD*EhZP+pqEo#^JYcVgQ;vE!-mr+TA#yY2eXF zI#+gp2cjL{+6A!zpL`%MWf}4JCUeiE>qMFP59Hj7-sWqJf6N)ih4n#}G!X{B#ZJ#+ z6SQfv{l`9Lom@hJes7K|A4Cf9Iebwm*puX20+I{XW;Z&N&xma-*bQI$3r5e`oly6_ae86G~D7YDOlsMCtqL3sE{pofUf% zZpnQ-_*_vy%|S;%d3AHE6bf3U%X9Q_GYJ`C$RLLH&d_i4ZA{n{!=iqC>t2jK z?y9qIUAAG?a|(ajte60`BR}LJ*@f(iK6&kx5vyzQWJ_5P#4Dpt-A`9p7xFmBgWFQm zWz_9HliefNxP>bJTIo|WDp`ihLesqaz(5vm&-=NNWY;yg-smVT9Zd~1x8-U%S)Cdr zB!#MN#IYny)4R@N@A&c8w5Q&welst@%Ef^;V)GZy3J>t%42C38j)QGV@~OvttHx` z?!gSGivuYL>8k=WHJx}=U^zM^vj~aHC^gq>tt4o|O&3w68c|Y>Qq_ljtqNcP02kKS z#=?cHOdDk-1R4WrW+?1=a;l;$9@d)wY109$*^t2%{0|<|K&QYS2Stq9fgr^Cxm6F3 zsEI*ZhiJnNleQbIRvvE;+iB`nmw$LjMm_z zVNZPvP)+5JSDR0*PYB0?m=N{g`=~+Ple#pJKw}4!*V~SUHR3h_m_;}9P8+eR0-1Ye z5Ej#K^!>yzyCm4kq*NS(U@fnbUMcQ5<@{TD&Oe~}RKXh6aMcmDl><3vRcF%TjMyn(eF z8A67v&!~% z-*tzsOr|R6C`?6nY0f(pUU*#iWk6tgXU?&;z2YlU9vVF#zAe(3^HRBAuT#xt^ShTE ztfT@mtBU)7cSt;yk<4_-T^pO(uVbFK8f-IR-O}N~zw#0S3~nl%7c!k0i+M#~sI|Pe zY_fMbPus3wF8JK_1&?sSw%WXBX~gaxbJUT=Q~Kyp z1xD$Q2^1HN&GX{oeNq`3a^Ds!~U` zDKkAIH6PxQ)<`c^Sjs<+g>CgA3`*EZr(Zd7bEM30TaS2=ulZEGz&Ee&6_=OpZ+c`x zvx*CTz_v%l_`-!fB^EB&k&xT@PG_}(L9-GoR?AC zeJKL-&3W^haG?fOEe)CC=?N^|BOrTv)MQO&KB!0GSaH8;i*;C zPI*^*++LjN{G=pNl{JHv}DgK=%&n^!W& zbyqZ%pZ7hpBGip8_8I)l$@_LNuP^%6X{PVT>wF!zo&7L7U}6&cyib( z{pE+2J^y?LA(&1HxxuiK7up>&Bx(w~$pc5f})Of$?RqH^&${hb}jv*WVz=Y>n6 zUdOyl{rxzKg+P_Z;DB^RKhg8)^NpI41+xXnVWZMT2ZzRy0`RBMQ7M+AWFECm!5IMc zI3#({Z!LwS1T#hCfxd?siAWuXG*?}KY6cIrhvCX;zXL${q<;ji4(3m`z{1D}XH^Mk z!{5a^!$NM{h$vpTU_As4HpCzB88ZO)ix^j<1krZTwZv^QoHo`FOyOWn@0?-cnC0t4 zR1m{{n4XT^jM0#gg8PBp=I?Y0*m|Adc|y#ofE0oYxImdKyFos}!0vDz+_oO6YDo@V z|03;%!Vc%pyk?7l>X6kKdB>z`wkbjh(g{qH#nV5xr=X}r!Wn`i7PdabgXF145Mi+C z0xgEoBx9;3o7pfVI>ZQrvJr9$ZvBfo7ykxB^tm$qCLW0C5m0Y0`nV z%Z6ugJn3`+Xsgq7FF^k`Wv!P9{6l%N1M2#N7FC^-Gk;Kt46}rJ(G$~vBs!*G6*(**=*Ki?oU(;hiI_YV}1H7^f}cgt^4~j z7{=Oc=yIOT!)F!sWO9zwFE32t`1ocC1XtWj0jhv|ZL*wPn$7qA`EoVtD9u~5ac4te zNc+~>3N1se8*wkyBnJTd-Z$@R2z^d8I5~ej@5iH8wy&02)$jX1q#K>^pc3={t_vdzu;1AEK`R2B1Yc=%I`?Vta`(@nkgUXYQAQ@6p?jUCdkIu*Gre zmY!PYTuF?!niq5e7=Rwx9l_P~_|$E$ArYoE9a0Th5)Yfj0%beH+O`L@Z$D`yI*7qJ z9o1!ue`U=AG*gy@^BIG2hcu`r&5HwA)g!YCMy9!75zym#qO>^Pmq4|oD&VTHQ9ffv zo&e|`!7Mz@Zn)kG;>UHRQ14Rj;03#JTMH)AGj}hOOR%V67FyCi5fi>U#f^a zENY4Qits|Zn%utPwWl!z^Rnpsi61Pb>+`ZoFqec^%u#}UGF=cRirl@)Ij+CL43wE^ z=4~v4g0|9|sviS-31jdlY^5pSIO1eaFmu5dIDiLSni>;k^74O5cort)aI-St%Y#I! zeCtHy@n4Mw>TiJ0jW8!vm)w^MCdERdgdL5c-MM^Z{G3Dz+Y{v2q+ zi2p-)E*kr>FaiP84q1rUfyH2hJi@q1ffYmnT3RHr;WR9q?)$bvOg zs}EDUQm)WYm%&109X%?CdgIAKc0Qg$&M%$ z(HOt?N&Yw%U}$1!+8Hc5G!HC;WwWdX$31A;7=x81E;Y0Q0m(pGAZ@b^0U^@pK~5>q z1bi&^YFhNk7P)_=&~+5*9R%cV@ISgh-~CT>5bAdT7yoq%5iE>+#sA$vhX5I_|4Rz} zeImFK&MIVg_zy?_2c6-e8_vrO4HEJ^^nZy&RzNo#2$n`3yKxr}beG3Q02)iO>-v*7 zg??I7hAVBA?xC;LZUvlWU!VJfsvvCcQNQkk!5H?6>iz}Pe!9AVrI8^N8@)>n@{d2L z=|3pWmG`eW97vVOukHB=q}~?syZJ(wfY+78k^H8>J(a^{bL-zhhES-eSN!tTY+84@ zr|LJ#v9~ApF})}am21B!HLnwo zc*=3rBRoHJK2H5Y^!K(Z14Y$Qn!Ds>-H7w0)ay33Czi5it!P#DIqyVfs%J&DK3=@m zE}5UIn0S%ozgVNPZ$9_O5SsqcL{smPCc(O_pI3Aayx3N}b9tw>{j@kg@Y5%H-D$a& zqMJzh^<^~9yYHe|$@eE)^@|HVjiu9W-hAiVmgY)csPG(<9CGDU|0VQBB0w|1Ceyq8 zlC&Fz?`+v>0ds%Oo^aoKsR-E?_wbHN#*5eH)sI_zwo-Hp(+v(E$+YPa6BEBK8f`Xx z;db}MG>Y!~I}v$-NA7+P?91u0d2-~5=QXLzk){fogOwin7nnnhyLU>J?|mq!<~!lG zSFCm+zpKP5VE(%z?xIzmIwN!0+jr(k%sEN7ney^0Ic`@U@dQK*C9cF`B$cRA&;R+9 ze|e_wU}K0Y?WafL$xv_Mmm(JYPThyEP$pmG^$poB#2@RHuZ+9PZ4n*3=%8trUo4|? zLFKmz{+QVfx}5H_Aho?b65g&6;StQojEmAEs^^ykM7_uI(u&$;b-U#S<+mAbDjBQD z7?VHSP-xt$0Cm!aJdpzf!-4+^~D4g{=cD}GIW46um z`?6Vlfu7E*VmAemkryG-rj;Qg#VYmEeNU|0l?@Wwn0r&7c0AdVU7Of+DWjS66q$b% z$0gmP^z$dbg<6^Q(}R7Y#GkL#xDBmsZA=cv`x#zf7PGSd`gC4d=lVeYXR*P%znI%H z9cyk36!Bx%>@Ds&rr+m&96skWhsPl<*dpOw%8cXJB_aY zjLQ&`+MfOj>QH2kj2?RCLv?C&tJk7U^%(;+_c&H2Cor0Ej_zT5NcncJv^w8~-t&6S z-}I*^?N;9OnA|>jMz8n_L|nH~cJaMwopL&7DQaMW9s2dchx=pU`Q=!fV*G(20TL5D zQ*@xH{qh}7HEzF7^qK$$s~?s|G-ar z^XJx&DQUdaT+KfHHF?-FBtKo}icG^!neOjFGd6#D+*`UEIWnxZA&)PI32a+D^*zK zOW4A-!`gJ^qI^t|Yvl0UMen)?g096CUNbw|$>rppIF-@Gt9M%EKRVR+E3h=G-rnbU zw)r=6AGzJOD5yP z#gcCxMn2?Pqwu}2==6x?7WK)_J3r;Zi&ZD_HY4c~=WMOOlAQRRXa9jXRL0K_d1wlc zFvM|j15F?W#X%RSAMq$OnE2l_>-C#i6P?llVo7a~o5@wWt_7fpg+^=&$|PSWVAT{@ zIhxC*kA<-#O`8(_(q(GsE^m;qV$`Y7jhQ(ks}!Iu#d0IX4rCWZ7CKasDIARmwT6(d z;MxW36^rhQIpnmQ#S(}XlUEvkQu~QqfJ%=^r#GTepx$%1<0Y2?&2bDltq^kn!2|07{pgpV;vgmC|RDo@`h+9#lj0}_G5Q8b)oc4Ty7$|F%J57&oN!YK>(gf zJDly{fRPbvglA|55UwY7 zd!Q7ij18}MFB0P+wgXyk{_>|i1H)Y_+>+~`WbeRbnN@NH4Tf>-m!zr^QGC>*u`RvY zWKER}Hc}nb)P4$vDxDx;fehL-EZZ!kTpMk*cNlr7G`Z{}r6u!t4%%d*Q^w#}E+6im z!eJfNya?YWx^cV@k9W54d(&b@WJ~OV6jYJ zWpd}cuwJvORFY;%e%+|8zA_m0ajJGQYcb7r##2oRJ@s`n!Q<03(c)hNThfJVRf(i@U~uN z6dR61&9g0o0j+MTR62;grL3VQVJj9LOmCD>;rXu?4}TNY_#y zgaZfE?O*IUhS{Wio0;Csda2bf!|o1=^`^qBk##;Jlj5S@^6V(o&(@nMe3~SI0x+C| zCfMo8JEG~OXJlKKdVbROPc0gPXi$hDR&%UfV9itv$o~*Jo&{QPQmDEdK7LZs#Ipa# zEag4^>h}z^a{1oW^ezwOvWiMyyVS6HIzFio+bZ+3t1{`dX){Yw<4iLN@UTi6^}1fg z`|By2MuJ*g;+od6Z&ZyJwA9gBU>sw|>via!}Zj z4M6+RcvNJwIZu1^x87Bi48lm*Ci2@>@_R(n1@*n_zqI$y7QpbLNM(iu3A2vGV&QAc zg3H+$MDs}b2i7CN;2;Hte#}OyaDg>IaSeeqC<-@mh_vX@P`Z}TD?R;{0DlmGk^#`W z3&=_~dq6WTMF^x}(20}NtCm2c#uV`ElMo`@0+^jO?5Kk!;Q&XPUkUB%yLEHMoVX~A8 zu=BbeD6|n?QgaN-MCg_b-d!mWGTL@SV}=^ ziH$-L>>Xt{`R(+O#7jZT#V(xXySqJ&&`|COovU#C^`3GsU$gy<%A5T7c007ZZ-yF5 zk|gFKIk47a@(Q=Tep`PGP1!Mf7O#@BdCPM4mu0fgLm(MI^&u|NvCjm`y9g#K+`K!x>x3p(omYwrIW zgY%aR_^&A2sPyQ_x{Vy^jSB7GTJZ0UaBXZr z^J1`eW6R>sA5!U}E7RF-^KGsA14jwj6Y3RHR#T@pztZLLFsI?^y?(Ph zcPROKjQ5r1lRIR_>DUkGOU1uhhfaUuziI6v^Q2{N?wpNYdee#Du3g1BMC>3RKCZnb-c}>@ ze%&{Z+#&in-;v)+=_{vJ?iW+^0`TZ$p2!^BoTQ){*F)Y(jPv-QpW zz%c2}D5e)(-Im(2rD%epKJ1*8r>IbrH>MnDRI+mBz=v+!J~!!@tHnGTt)b6Pi%&|R zjjjHHQb3=>@b$^Ut|f|SCuISWg>(m7r+9NceMLp5WhlRYQ0Q9+Pc0aj5Du;orq;_I zCrK9)+fF(X7uU-mMbGrzlZU$t#+R|nt3OJ+j+(r(i#1_xO1lwxjr2<{;Nw#P?6;b+ z^K8tq+lR_8crLJYy;?O1oe=PK%71(^(LC@zrM+qW$FnJZN}Yjd?D{z&*QK+=&2?vp zWopOzPuG7s>Drn(d~OR3$rK+NQ(wHNC!~1XlCyKbd2klhW+VIJ%C>KIO{V;mPl|{*tIxraEef`R6tq!EozMT+ehcsq=26w6e+zBdoh=HUaP4~ zoe%j#&$MiBbyD1|o7~rI*u-X$(nvmbRV=KGWA@3c+?{^{XKQ43n=mq41#UjynR8vH zV?l<9o-dhkB^6PL9#mrDkNdghojZ}|6`{-4D^3NKcl zD(<@7Khu7pP(3jA`e^x5nyb;$v&ma#-N7%F$5L8D-@muo<_jQzmD<&uztH$5|8a%P zj$GpBU-f&HF1=kyuL+5*zT|UvHfh+fxFK?R)-u>*R^h7oj-aw%>CSJt-i1^=Ue<*iNdG^eOU8TLG9wftK__0Vj_kI zr&PM`J~lPy{o)ima`jwo-WA2pix52=r9Xqa?gX)?@}+&n2R`hz@wFtn!RgxE>5=PPM*c{7Gfv!QDY z-nAJG7uvy3F&A;t^j}YWGCa%Rbsj<-;bi~QjxD0U(|=odWQi_Cg7_|Do4SPhfTcJ^ z{@_Y#!je(!hmTiQhQ_TjA}Xg3$&Pidn^o5?R^95jn!&dg|Ksh@Z}8eYSkA~yu>rZ+3mb4Dvw}Kr#g-wE#z4Hp?8H|dzF zpwk&BvT6#a2;yT@;bHP=3*-vQf{+#`ob8I+d@41%&H;>MUtym1ee7M(rf;Oq$&)fu z@26~@)uR#0q1qYKX9Tq-DGmAwYvKjc2cel2)S3^mJ?yDb7+cxVElt&n0-R_e{cL)m~5GII+qz4?1Cqm??5!tN=H9}FRZ zMV}1BXv=caR;ASN;m+O z!@4h=zZ-BVP5vmIz_a_1JMBznR&&5tGlJljx=q=aaGZ)qjy^esXBDNe}ct>Zk%e5bH#BApE1_;e3|<6h12&!CI7%) zx@c^BM69Gg*C`^=@uZ^t=jtnkULq8)c0WNK!`g=Oe!&SmQtheIVPJbfrPpL@dS}V< zwdz~D#&LX58VaEZdOl9QQT-YC*K!s8_~Kh^@AKQ%x5R zqw5GDjdR6Rh#g&u?P-0rHk`sSNY$rWQZJqDI-c9m#J>sSX6E^uL11B~CKzn;+vP_> zV6?_xX%;A;NB*DM1+X6m1+9_PxUITC`g0QeeCHLGo}RNh_vW83C0{8-l%uQ!+**^P^gVTbq*oxT=4 z0Ua6211?^u`p{9Yq3eSvxR6HFR%kAR6kb)$GZ*l=q$ea%i~;hLgV`*W3_$mw4&4yo zXh;Ia#Ewv*O^D*c$V=4$`v4t7SKPLb^tz0%0KnA_M47ONdV;&-MoO#u>gZNS_*~3$ zYLK@k1W6YqXo%a~mY&{-O@hnxuAbge6+-P@T{GfK&haOA-4-+T|bU~DhxV+&vB*6j} z7^)=?&_2)`VLhEja&`!b+6hk$ijjW{4y132EHfJ&K3HYZr~>3q$PXgO+p41hx4xK{zs<;0wy!w|VGD%)PadEBd zyI~)sSXi6^8|vP?!X}-?rj<4^&FS^1u8RZE=|Kc?>EH%y!2whJ@3@%&qBr&_Em18Y zOKkSpYet}rV}mh4WctdZ{4ZCNXSO7GE#8`+up}#5pI_-rov|&k58cCK{>+7GB~=oF zm&4Ril9Z^U-VxW!lyXG0Wxw~FbPlgIxMkW=CT!WGqn!98@jGkjjc+!N^LnJ226~y>*O~9`AAky3XH6wbXkWi7)Ps@-;3LeYn{acg);=RlK;e z7i_L?gjXFZCSSSU;-i`dI6wUcGYjfN4){*s;|`(^zq-lOIOoik^E7XZ=+sV&Ia$rV z-V1`mGc%onqn48z(npEoF}n^Y@0W`X2_-O`jyMOkNOSC?G#L06nyj$Su4EUlmr>@k z7y9-`2!!wLwe6Ct{Pb?!?8^EMlT~xQjUtYplGx=fRhs!dm$e`+|4O)l9dS${IBMRBqy$ocUs_ z>@j6^=)%6%)s)YZ!h&M9?!Oy{Wl_op&t1kS$8OU!58mmaGdCQ&9@FT`~?MTGGq+&fedRh}?8 zna&n=yK3AjGf-<)FL`ZfK2KbzzeUlepf6%_re`+9aP|pF;fT2=-hATxy0`tZ*>yr& zuY>n>V$zc@SvD(m<3Ytm?q_4lI0g+K+gv>2n>>V1HNL3N@a_5>T8ieLdg>jMESYru zLDPulkkpz?sq=xFjw3VD+s1<(3>DS5K^Z0XO!G58hr{TlwG1e2 zh+Gfn8XCx+I!;ps^V$tuKjuh3d(H9pBt#s&*fNVPnVrG>uPqHb)0_up!7yEKVKGRT zb=W;J#(P30D#s=TggwCYzapC{lwxd z-^yP?Rn<;Q*}UB;wwhy|b1>CrJLnbiPM;=F&rnUX1z)9w&fSHyWb@2NZyi-A9UAIO z3+lOcqyP`*)%E6F(cOFt0v#)itaba}CV@uwQsfQiA?AI8pUv+i`JIT>k@+Eu6>Cf z58@l!7w?z6UbTRJ%QKcW8A?^kT9yy;zbxDR>(X|AP+E?S>n|W>YF~$XX=R1gZt7be zE^noQ(a|-T#{xMvX{~G?a%~$(O zRsPCBGtn=z#h-3mc>HM_Db&br*Zs_imWgYQ;_dxZ%21W_#lHRDr=R(3T~~*4hcq;s z8@eNTDdu*6KTe%!Jf`G!aLV+>+O#o^*5f;OWHChAX7i+t@U`0J;_s1`N+EPYn-AxD zgVl$-KEdkz>((Vcq9fGSwGP)LyhDWbBG*ff zu0~M@c1|8_Hi>=z&`RfuaGcN8f>zB5Wv`WgZh49_O1|X3Ms7)PilKC>f2HL9<12o# z(|)%Lbbq0U2ttYoA==PzS@L?BG7MXl&c3Z5<#AGgt&Xy&17@BaF)Kn@!sNQRzAqQY zwHwZRPnj=PUm4Hz%od}(grU)N-g_Zd++~nzvSDdLm!ji<>BS+svrA}141tjGKo}BH z+eolOatHsrtEnCE6V~|8K=rkn3?$sf4oH~5#zAfH5owQPa`Zx5Qplk@U_-vJK95-}PtT#wMR`9XWa1c%lcy7aHm>LT*HHbOJaDXp1$~ugI zI0lqyat1)Mt8N-e)e!ZLTzW%1t>**QR?og}m@bSTjEEZa<6bS8pl8Qp%Y#8n!VVj* z?oVQX!9U#P6+c*_jPNKUHat259LD8tp$p`K!Fyzow$l_0G!DP>lIn47($ztyMcLN0 z>a&md2fr)I{ymqe`R@Ek#tvm6)E4gQqO9*JqdK}A0$9HY3~OG0dm5OB;TS6o^ymf1UAmc$YP}O%;j@Jn<1vv1EquZ7f~>= z5xZ%7El0HG;ogHrA9u%esi zD9jhfx4I0e4}fy8eysBPUWIo0Y+z6MqsGp+9+6kq6jm=j$lU+p+OtO5Np z;TnCZ_vREMC^Qqh{b}u0TlaTANTSNWn%M$m*~dvqwSMhr_SVv zIoei%VG+*klFSkj#|%jEf$qbq=}<9geGwc(pwQHHyG--r1vi>yFlGZu~F{>2;w6N|D$HVL)T?;T~N*<~u-IO~eLTYZ?d*>I7BGGYm4 zPF3Jjc9!{xcv1MJSflIKg&a|`$Knm3te`_YPMUBQ3$p|?N=J7j2Drs!Fh;_*7&L<2 z8jTbu7XW0ZZ}?0ARO@q~H*!!$l8^wSWBxjzaAFp80eKDzF^FeI+NGd7gsu=7Joa0| zbu=VccOOW?S4*W_rh4q7r?3V7-!@9!W%r;sALO!dfG59 z3T4xx=}T0Fe#U7sUKx$L%lI~tt^%h!jPu0*K`Fr}W0Opv5quq-wvDmN$|_?+s!1$l zQQ_?EG0WL_wr!Yn$YOTKZG(by2ifl~gH2E8Jv38V$xtwpk9vXI1C=Hj6FFtXvWks@ zDWg05pf8trn#9!HzUV*b&Ja5Vr{Z z1V`g;X%M%+-eA$R@XGC4RmkR9Z&LXCuMDrvO8nm5qdX4W4t@7}2} z{ZVlblv9Xt2(c#pS7bry1;yrnRT=zi0!wA6*KdoHfbL;%&sR#CcID5Gli!?rrwBE{ zO-QwLL5Y`+M%qgI;PZewItsS6sQ)B^@QVpF!_)s8cnTLL@}e7ZK?ntcy-fkJtjDFs zAaUkYB2EHvp%z=eb9!R8{_Ehcyz;ZGR(roWt&99YiCL;hICPJBJ?DFvmslI*IALk_ zYm%;U;u$ew*j87UC{y4sht%>Lg(SeOw}`rcJyV8%1uh00xqH0q-s{s+ePTj$yn89R z`p5OMC_9LiYp+1D;~@2gM|k4G)i2cJMv?<bn3Z;ZnueNDZ^MJ?)B7OveZbtxz)i zce*uPBQakkpoZmuA1)q8lGmv7?Z;Q2YF4oqv*u&Ggm7NU1hPf>@s&sCl)j5r8r`g| zQ20qZUp(1)jKV&o_+gS~6>Gm1{j?;cX64Mwm;?2pXt>tS<|!<7h@gn_>g5_dJ-hDb zMY_G{srmF}Igt2eS|{W@->lNNa2r9*z5VT_$7v?wLFIy9o$E<{6SG)JZ;NeYfG@}vJ34fNmqE@`i$@a(h;c!+kCy9o@el!igZ8v zMQ2F#l;!mFwyaOemPgiB1kzT#S5|&a&L3rUh`Hk(?m*OUm#K7%Thj|#lcP1}3MXBd z927&pIb|{`u<2F)nHTUiXm2$?d#)vcX+iqRqjLMpMOo;hlvRa#5AfaTFiE@kQGV-9 zuRX7)Km}JVksjb4r9VBF_o(WUV%@@JQ$-)yx$j!%ZrAk;JuWX}?o!SrOY7#um?RU$ z{r7M_n4p);953Yj{{1k^N?PBGR)dnh-40N>JPugB>Ui9ES3gZSxbqLnI`OeYaqsLQ zNFh9Ab^=$NNzOlmvNP;+`s^Fc`5-~)`q-)Ew<1q!Wdj-yy*coLlqjZGE?UdU-(ZFR zZrLRLiX-}!|J&6p;+8QYLc?%n^34<*={&n*?2SOC{+Am@(_M$IgRP<9XOH?&&$@qNiWUY&*4Fl2>qXRCZRjI^}!irs%2b z9j9}>9Ly?5=_gIAUo6`^ye4LAtJ>f`6=``P=H0GM>-@C_ugzB0PG7whxh>fxdyD0O z@8!{Ra<<#0i+fWqa_v|O83NBm*!9Q6?~A-aw`MJ+kJKy8z8$sN7M|sF+1c}lSWQb@ zt*;!dC(@uWnsxp{)%{heJ}LX1JCcUn7V|m`j2BS3pGVl1DfdoaPdJh3SiViYL}9s2 zxV(c=>2d9u+02*7;niR+rLBn*AEDU$4^CeXvi0&Q>H9D=-l+7@K`ifA%T~5E9_y=> zGrQs`orY`d=1uqGu!O_I+?mtES9e++T(S23gOUc$KFW8O>U9MW7620ul9EWhl9v+> zux-HVauh9u!JJyoMh#-37FG)P9ED~-;NwOZcZoPYkkyU@1&lo`DX;*-{~}4<2)Bwx zeP!N9wm>=jND^+FRu^+u52VI{h~aK{c=3^O&_h6Aoiw9dGePX2KRz`HQU9P0q7jvm zg5f^c<1^_f?1pTes%tTUq<bA=AXr`&eTgw$Jd(00lomt- zm4U=DM5hc88}>pYwiiOQLCBzi#2BJ3K?=2@wq|=EOfEnOVkjnL!7GExXnnX$=In){ zLxG@&i4IU|{!)u(*^Rx+58HM&(rAA#Q`f;6RUF(vEMuZ%} zS(u!C-L2`(zS2-i3z2%4!dbiTpKzt@{t!d6T5P>Oj7&;1`st;l(xhIWB!1bY zK}VQ}xhz+3_-FG0E`?K^9%ybU2sJIiqEcvEu#)Q3000D*$rZZ0-6k^z{dOn6W+oCM zPgR3sxw|Mqm-ixFS<-*oyEJloCa0S2ijf?Ur==+z8okL0g&evqf?NX$H1SKH&pVyS z+J0qtnMlQKWPSuucB5IPL~ns_pgArjnMOsqXAzzI=&C7D<-y(wa*%3S)?NOZNU{fm zftYJkK>g(C0DkOQ+}6fpkyzl1Uy@Ukkc|xtgsSxFeLIlJMsRP0aNS^HHv(B%9L^Mz z%vSM7O|nn`U;!^K%%D?&#zy$y|5FB#HkK-71lPsh>*dR=9+;Xweer8m`oqv%m z(TNOVBe1}=0tkl&M3PwzrNV@}S&n(BMHA1uD{`_WvM3hKO>${0iqPRYGGqV@Hdjn- zqc*2zcdUnwu_oPA#x&|J54^qoWV)Wxm=UROH?%TR!HmYz2%Zu@E_Es*@6;V43Ibq<-!!wHSjWG`vIFWgRD^GwLE(5`tDY zrq?5o33v>I0*BQEe!vTdSRFQgkYn|q@aONph<^iFT>qXf8$k3g)I@rW2=4nAh{8&Z z&WhgWMH)g8yD-<3_}a^FJ^3ztL@`+*%b7S(I@r_Wm)^QOlLJsTz8) zZ~)Lj#<-P-bMUbkfJM2R@e&gM37r6*T1S~BoOgGZ{-^ThXN<1HzUcZW3k`_D9;fiU zPhPPHy~6twM^@({>N&~%nU(0sk?=Tlbn%hEylAg~`mS8b)UCbo?csuMP;k)K`P|FI zowE`d_e~sb4BB7H87E#j^V&JySY1fMTyBOvL5@^?ZO@LyrOPJg7R_ggCmZ78Ri_va z+V1*iJdmQ(xrhbZyQBxtTFOtJjcW~wzgh0kU3$&)+1fMpI8R$HX&tc}2{sSv`T}#c zh>~%4BGCnQaR_ka&_VC$Ia$Y-l;7-;b?(|Ex%8 zYR+N1#*Ui_`8?j@dHd6sgY$V8GI`H;RmF)v19r;%+anEDC{m*c6V8(@g_Y&7jetlM z7ElIU_F#yFLmdPu3&_C(QCLeJY)pd@Mb`=}Djt;8r#ag8p2w4294B{js~^d=7s`(+ zJrKJ0 zK^Chvw#7hP5$t9*jKK&$5dlW5EHWF(k^%eXqL5|iWOfFuwfEaro~DgfOF~JuQGBpB z_vmePqFNZJ2U0`MJtphb|D5oX@4YdY0ON2-h|nz-O|XH>7T!N--Zt7^D9k}ngh?Rc z04YdHpl;bv2O#tpoVQT9qLD;JV*_?53Ez!wgK>2zLw3h6POd1L zth&`oLZgPF>t7D|XEgu()SUqBH1Li>XZWsTYR2s1sbO8}itkWJ&cs~GW=s{fm7s;= zQAy9-3Aq+@v=GQD(RV<3sj=Y!JxT_}07{N1uiC4HO|Hgm;*phtW!Wx-l(q@N99jyC zCV}$6=?G1xYIN(fuMIog3{M{RsU%)HsOEL#WI>lJA;`-&36m1cM5RyCxqJ&4G3YVcMi0 zTKlCbn~)amMlH9A7`8TsprJaXYE{53(_nSE?Qbzm42c!-24hIVfs<^&jJEY=CsrfpP4}uso1q9`BT&B57k1x92 z%ed6cYW+Ck*nSN=t~FdnOMo_eCacAXB~Wdk+-n=UqF9PY9GplgmksotGQLjqPHB=@ z$%YMum3NsU%n044MVKXo|ES5`&@FaC3WYmYSrdJ<5ntsq6`Lz1aUNc+yz+jedNl|} zjrD4OF~EnsBcsOZS*2HnrYms9tn>qLuE0{OB06}1d~#m&XEPA3sKHMVXb?9cAea$G zp+>HaDa^o5I;H;pOZo~^#7J%#CKE{Pa~=SY=J5)5CukR)-L!KnZo8w5hR(s>tcSfw zO3B-d)_^^bZ`Pt0+<=GBF{}w*a2Yhl6n?Bpq;Sm?5#`C%sv~O{7IJIW7&b4f{= zIYj>rzgjgd&1em=7zQ7yDm{&QW~P}Xz<_&DC;mrt2;z- z8$nJir;Q1TuA0GS;6)gOKiv<2nPnS0Kg4bUqlLT=P=am%0*>m9U=$>{?QdiX92;b1 z{NJq6M)9VLDF9&8f@lZ+4{iYB>ThH;@`M}YB(l|SZ1HeV5X`XwDG*e!!AT;}f`t49 z(K7yp1b^@L_pZQVkT#$NQVqgm{`)}?1#5Kes(1M4rZ(o&@jn42{X4okw4iB^UHHkN~Cm%j4jrOrwP`=;W zc`@jY^g?8&aGO_8+LbGtf;~rM5|)GxT3kFLa`NJBT$Dw;x-YF09(+2Uy68>^^?;JJX50 zr(!r=dEvS6J+;94Uc>g1gdClp_A^d9d4dAE%1&^t-=wq*FEe?=7KaK?4dzGM)||8# z{k*6r8${TH2U9qL18 zPafc0vG$zb8h{KQ86HRo_S%*dEFO!A)<9c4vr(0?*UYER_e!i}l`cNB$&0PhJ>Hqn zqBWmqY1)H%IT#s!`^PTPp2%O`xnYl^FTQ>HoQ7M^pRlF=&J;rZ(pSFKRnZ=deW z;}E^9_)b^lVYOad#$d3_)HbbGN};bhK6#J4%@xaYP_J@buC2Cbo3-%ZFjroPDBY3o zRMTwrd4F&IgRhUH3yx#&X^saesn+V!Q&1gMUcY8!Zk?^TC5(-cEq`?HdpOj;y5ByS zXFZiNkrhw17v&BeD0i-bks=leRSMEhREk_>DZ_tIFSinFI{^r)bYfoRw7Jfhk!Lj{?uF}L z*{ooo@PuZlk-{AH2t{RbH(QzwNxv-pX)lvl}^mo|<{=+U$OY;KsiZt9J zK0Gh+8ZR-A&gV+JMU}fYa=U1KVn4^#*XvD%Kuqc_%^K^ack17}9c}0_Zuv;w|3YJ; z0a<$CdB(|jX-A5@s{E7Q6R=e{hgy-s}puwhs-o|+8#vK0?zo1gJ7u&R@4~xurV}yU-SN?MYF=0V5PZ#a9tS;p3uo^8Ls&*5=eKR?Ht zqt$v5HhJob#mweYg_TD3gIcF>qRo`P!C&v+Qg<4}Rpv}OQiKvhY9F}mOnC-s1BEaJ z5F-kJ0}=WVW5qu=YKViriJ@W+Y?2aC;~;lLh(t{haM>m>1F%FtLL<+RzzpeifZd_k zP0D!IMSqh-5_kv&u^yzt&?YAm_d?SivJu0k16T*yQy4^B%Y-ENNX|k5gDB)Z*fcCM z(L`3CA=5-X6BVw54Pnu|PDXiaVNyVj(nEUnc8BY=qrJ5mmU3!XpAG1Ls>wngKZ5d(V^7}Qj$@g>W%P28rBIZ%^%A} z6y@N!i3TYo&MB;Y?xdmkAi$F4bS>#Zt zbey@ek{6D*rn8;g5Zl6^J7xp@g&ME-7|H2vaLn>IPyTvo*FtAtfY}Yy4~A_q z%cJ?>5*m;Xdi!i4ZtlAEwTFkI|uKF+bRL?BsXzSB}PiP*T(3gCvOW$ULh( z`N}Q;P$?Z>c!iIAvYOFa38kYS+g`AiJfgb(4xiz?qe>DH-@x)BVs`aQ7UYwml zBT<4G(*~Ii4_*XKwR3@mW7N<6J5sv)1@-}*liSc*MCq)F_WY1y6h$ZM^lLnfK599_ zqP0jq90vdHbGLMBmHxQmq6F{bjNx$K5!-sdBIUC+(Ss;==XXdEaH^MFP%NvD-uuGX ztIj8n#^ta3smlu{=J!6Hvc9m`aU;1nQ8Ma=O{b@6U3*)t7p=tvB+Y` zs2|-BEd_0b!bm(QDyIsnJE+ANNklkrh}3CCWPU;@1XwXnxJfFQ5YE00Pt#&uLZkA)KTUYep7B-|>RD%{#&KZzvQWs>Bw{YBHtem;o{J(w& zXT4y+Ia4!P*eGw2Bo>(mGR%_-LuJ|ZIa{J zl$V4jAnLNjZtsbqd=827Kkw3i`QSU=tgrD`j~{d6K*wGmdGlR|@bQDkkCJT0qav|J zOGoH_KD8MrGQ_3@^U5kb8TcLSb4!{-;eDh!ABF$BdD+OJwkg{oh4%h|4gBkhs+%^- zFRptx`bfK$?|m@UvH#w*=v#_qvPHTsr~j9tc1(hy$`(PNdDi2`gCL`W7BZQmYIh&@ zM+D^z&&*YuIUEl8z?%5Yq~UCC{Eu@6oPrv5HQ#Nof{}34Xk*4E588>VGgw0MfMjUq z+Y~mJ6|}p&RdVE)u~NZ)NQZ_o>J98R-x&mLm;D{W-Yr;J`J|Vg*-m^WfAgoRDYmdF zU8p~zM8HkZ@W69o&2nP^E9}w-9JcmsO{=w*e6ry$Z*z}&WbCLly5(~Bf#-JkHdHja zU$ee`FZRk^OdAb$smOJh>$+9RY4|wWBwXT_tU+UnX3MYrhYSuTwB)GGKh8+>99$t= z3_e;;JX?L>$PG$^dF7^oa!I@U-I)u7D2kn-@Rd&yL(#8tUjC3{?wj>LD4e1VgAH_7 z^xOGlR$Xx>_JQJu)2oW_n)lk*mL^SH-7tLrWUfiE*zn_ABJb7{+u_%GSC_X&s;0Mk zFIt=&&gcH&%4hGts3x*uq7%MmT`{fK9`L~Q=sR1rJ2Ak^%uj3#NG10Cc8-w;BKWG@ zyU1-0Oc>MsHwTTcQtpDEQZAhEqbyxwg(;pC$9e-kF^RAgSAtN)JgT~b1Np+Z*rLcR%?{-Qmw81hoB z$nASlsqM$Czp5@DxfblOF%WCjTK&y+)$qhrs#V6vHIMZC_5R(NNh7Pesl21L+U9@1 zeE+m1e`#wrvUj5JQgn9x*9En6Ccn!x+Z471e!LnjJAOB&bH&u;_v`K1hLB$90PJ#Y z_1hSf3)$ViUk5xeCFffne`;-2EgL?s8{>BP!#C-L#_J-DR@E%K>kaW^BgdCZ)OhtC ztKNC&WRbncdQ>~Q(snMq%Ut=#OC5HD?3TH;?DdE6bx#yt6Y_91DkGy4!=R0Dd27|Z z!4i|$doysw&Q$Nr4CP^B44s<27q0hGn!aieKDtZV#V# z)Lb6=dX;<9h^tulnQrN-W5xWVYAaSXBdc$6nx8J8Dy$bcK<_ib8J;cu^RmZkRndrn z!ps0~-E{obUxg)p76Nv=Tlmh-oi82Hm7O_S7!WkqSFx+q*2ZUhTjL7t1*RS{rk*k~ zHo{$^NfHsMyK%3)qq322Bu_6vN8#kstu>hVYcnVOZ_#MUNGks#Dum=CzTEhmX8p4z z(^1~9tG@idmkQtXnjhQBDHnFjw&L?zC+(Rk+%je!TTV89G313euNtpx^H|BMaXrvj z8YH{r+|(PTV)!^b>Qj@Ql~Cel($Whz{e9LYVk|b#`->$KvI>;rH+>G250$0D`sT;K z)>0t8R@h}?jw`|CA9T_3xa=+T{?>@G_om$8-29NM>uS|wQ|w9;B(1FdUpdzp^L~?F ztlsF66+S|E0xfAJGV;;koUmO~_Z73Qe_%L>j|EU#4w#?ah30 zW|DD6eOedFKp1BT)rE~%MeC=WB|S|weCXap=sVd!^v**_JOfIQLQd=HVxG@r?8430 zHIOy;r(R3FduYG<{v@?VY^7~jaxX!W{a6B#ZK?qJ01U%kJ?HjfuqyP`Ew1%)!N%S zvSEjmJR0H{P!GELC&tZ73Jetzi$aT2Z-W zT38X@=ntLT<6-PC<%i14X6HMd-|;_oDPvj)1}N;Qt8Nznnu|l2cm_!b@?&5uL9>(w zrOI*UapD0330h!%P4JB9OI^4#nde^bx#QzT?u{BdS)|y)P1`F%^A$L58RtwCdl4X4 z+HM^~E~v+&sYQ7*W|!|dIU)EpjJ>Ra@e77XaSM@*NC5%pl1~#y2JcMBgPx>^&plFV z5%zzFT}E;}01rz*49kHeB&LPBS^&ST;QNFfX5&%84tw1bIueX{TJ#2DVt__ z$P7-Syq`Z!zoFWNanLEN3=0Y5g@Cye#1GyGT0RXS3AzIhVYG}oYdbf*;u-h_N`hB& zt`Cln$q5nV!A%erj=j=jOgAH1rIO!=+Q$P2f^;f11`ZXLwuD@C0+1R#^*&&&g^>*gP|8cnw(XjFSV#W_ zy|+au6*THVyxK^v6OuLSBLu^$7|@}RfUkggY0@ag9(Na6+K!lLv(Bn3$3b){gD@1w zbQmWH+ySx%nIMsj0m}oj0wBR4NIgIu0|%fT-ormD@PT*?!tYeUSNZSyjr@yr-yy6I zb(x1U5vmt>Q=kU@hwPy)_fU5Naf1AndfV9p{`Z&g2x>xQH#{rV@CtXO&Sd)^)2oE4 z_Irb}6g`LId}7Ls@EuS~lz%Ewg#XF+gl55oU&Vn@?b}O5lo)6h(tW$9>Nce>a-gYy z&zzpFR;y~lAUzx+!n7bq4pB8=&sM+7+}m9@vCY30;fU|)uKOzZZ)L(7ZVmQ4jn3+c zbxWS##mzSG6K3w4tj%S)_T<7diE8&mbCMER`p2F>dSj#|4#8wau5P;*+ycMlm|cs# zv-UL7<{bb?%nS_T8(>hXZd5J$Ov!b(&qQh zdQM6i4ACC>oa#M!ZZGps&jcm4TSn)!$?wG}bh#JTRX$C)8$X7YBBH-31Al|k!i84? zN5-0l0`j-G@V$#4|DZHuQ)|Z4aY|njBKC;NjI3*x!9@vQm*}Q<1E41s;4-u>JR;;=+fpXigj5enKpkDAyMcf$WwHs|2`w%`Wu&0C z&OC)x!nOP{D|+(%x%kV5k(F8f+%jzMbP84VzE%Yc(rz=BgBLjk7>Rga=*9|K7KDz?k`8K5muv;QMswlv$vF^ zW3dJ)yVnY{yFM1i6pN?EELa*mVH=HUs(v0)f0^yxa8)^enFgJi*mBBeJpa{$D*;VR zKev7O@8#UQ@pbuQAvaTpqH0+?7#YW6)`K2}y#C&neU>~iuiGde+w*Q}Cf4n?Lghuq zgDN!}%#$nPVcsFfhWI!;wPwqDzir$jppx0Aj4ZY#Gaw^lW^s71mEtLof8^JUl?fr+ zbS)Na&Z*KjPWeACp_o@Z)z(b*T%hA`l#=$9xKN*#6K2O>pjK6Ptsi{6}PA$wEqo71*nNjKZP8uPm)5y!_Psq^U*Lkm3p-F5wcP_JE* z@%Z^NbIPaV8F403tgZV3y<%k|v6F|V_A_i$Nz(KY9R!fVSXGJG1n z#xo}k2xkU0Gwz#P8%BNHe0Sva#(;ylecSOm(~^U57!)v&+GP;)E5#y}YA9OC!5Je~U9mzseb!2&m8$YjD#lk`H=n-66 z$i|E}G6DovZp68WNDEL@AdDGOM8Izm;Q%nQ6!JJa4f=m_(?P+$ga+gc#vD)=Kx|+@ zndq{>BXVG5E4G^;irPD$|9U-y`A+&2ANlpA9SRc^Y^2RY^tHQ{n~2AkOgaL9wD1b;K{%2ze7pU;a1q(FK{WlGzjk%JNU=B}D9t{Gid4*}+kIR9&9@_5G6yQXIh zn5KyNe?^R(YP3smfRTpLY64nuwsDg3$9+35x`;hKvwUDE+J%`>NSkAFWbUsOv3M2 zlG_9Fb)!?PN;yuUdjUKW7}1ryFiag86yF5hhPm2bl9%$@_z*dzvyLQ0%ZfXbEw}>l z@Aij6*uHBpO+D#cq(Fm`ez$IfLh#c0EyYawDLe>VkEK%27CNR~9hx!T=V#jV%eYN{ zDvUuykO0MKGu`hVEO5}wHV26L*{vlbnSUvPPsoKNU06Ix8BN^ZjzYgIlTU}(MfHYv zBUQLhCx)Pp&1KhM-!4;p$cWurg0$XI4C<|@$Tp7%7bpZn);?OgyI?l9^E;>+#sQ5n zjE5V>?CmQJnngLD68Tj95E(k=QHz2}j3(+4N|`2ceVN8IXIa|If>+R?iEeG`Y(7Ie zhJGi=gV33ZhfG(O&;tpk-bQbRkWd&|z4S3T5Zu}V3)>WEpQ^>WPaZ&5UOCj#6IfGw zmqdHCotxw*IhkU1>m=Pb_;e*8U*4E5zpvE_Wo0)`gtN{E9oo}HV+a|YtdJlAd_Pz| zz%;6uLv<9xL z4>Z7obQ>?N$w0Lx1ICA|$muTJmu}OHMu-k{7&xH3ioiEPvmneN&K+vh-c%g*z`^0m z0R4+lpX-{cXEHQOiju*ZGal~)*Bk`bu!5YRX8>gphu&I#F1Ul4=wOtDGYw8O7n9nE zQWJRiEGNxWTSA?Uf7C_6bU!qU~=#cUfg&N0Gr%~8| zn+T{_2Sy7+docVL$%fgBlq6{2R;Wc1EEVt{Dy0Go4y+qA1b3XL2G}p1lA$q}14B-z zgjI{1NJOJ%f!POj0KBBgE$KE)PEGi%VEVEe6@wweSUfmOV9A6VH7xQ!z#ow-kUzlJ zNk#P3K>^gY_rG91Qk?zgVgJGU|MOeq36Ud(C3`1DWap(|dJ;fS3I7OXvc`&$-4_45WZnEevKh7R-)wF3hjLAnqmC~@cys-X!$ypt2DBCTFb zx9;X4d-jmYE}sn#@#$QC>ZNh{Z<3fv;6(h( z+i5H^kptGpe%#>wn{qOt<4NNE=@Pm4f|&uVU8m=yH1^Z5vW1!HHMbG};-r)Nti;%) z9a*A%wPG*Y%=BfObnp!K>Trd8QmFI4e09TO>~414PzU~o^QY+R!-vH@ersP-t5Msc zz!=GX1HB8SRb@Bs+vt2GhYZNcrn@}tCKDg|dOtmhbZS0Hwn{wSJWN-NIHtdm;`*tPBq_t4h%z;0Kli)UGRJ#X1 z^P}vR?6n6z*R#~6{C-+!mXJzDYVHNesF5!3)vz)#o~*sw8tK8hS&C>9$ydHH8%qgq|I;0vsun@S*qX5-W#dGvg5nR~lrUMA zjRqe331%8L^NM-i7C#)%mmE#33ky^H-WVY3rjgQY>b5DvBhlSXd4FThW@Uu;=RLiZ>X97Z{7UWZi{?8MLqBzgUi`L{Ja|wS-6wxp zq}(ef0g`IIv$}+-QCG`7UXQJ%TH60|9mMK4=mzk((WY|ue^bE6J|g+> zMxRk@&05kRFSjP||ErTnqhqY$!|9lI#fvqCl@*-{2e;CgmkNW&OEbLf@W<2NzFBPB zH1Bg(3t5!wNZ8{oJhnjiMn1Vx6I58pzMdb?b}yq5+A!HoVIl$4F0Mj z`$Af<;EQ`66(4H{INLyaI;xkmQtb_nES}k{qa5BL%mWhau-0^ZIei>BhZvq^sXwS| zAMDtbAL(c-g!s^ac1PExz$QceDHqr2mtb z`s4JbE02zT@%(H}+H`bc4*wq2VE-BWE8X0U^2r#WB0yCDqD|u@Y=SU=x?NH)@F^H; zuo=mtJGBM1IZ^bVA_IQ-XCuT14_?wjs4Cd4j-U~k4k|WPI!C$;^t9r7GoB#H!UM8Ajt4Wv}wWHq>DyRS6UlM z_RBaFjW@BL^lUwx(8IWpOwhd~$+lQ>t%nYK?g;++kD7re{67eh5fzn-EG7 z)i-(|5>gaGnL*D1@P_Qz*f=Dh06|Rfu^>(F{8#{5+?RNy-kAPI!u0y1UQh!_#Hlp1ty$D% zVy>||OlU1*aE238C66Wt(SbM+fB-gjU@7D9U`xkhKV$c91D!~)R7v$)CQgO2S|lI$ zn9xaY+wK?TM_gb)!m^5R+2g&$O4B>CBO~EO8dH*8W%-Nblc&tr6U!^k24Eo|Qe(t` z#8Mu*Zgu5p@RYowf&}7J$7! zSN6)~4B>hkbb;(rbdu0ueOea~b|({>P>@==W#kOz)rC)h?pQq+4B#j->L89@ALcg0 zcM5DepT?m%3YnSyRB0*0dIekSL#+2&9zb`f_4qZIT#&Rw8y#OdBnJ;@l9 zAw6CBAB#F9q66^=fRc>DPJufJp7ID1CWw&y(B{CCee8Yb9d#%`S972gfwOrQhpEbm zh4fCi)DL0+Q8K7tpmMo>+($W^F(U)UdK$Lm(CHB_DdV9|V9QD+(2T%8$Ux{>(M+&U zIU~=UlO(PeuOAOJfaZu{o&yW^5@ZsR!4gQ@tqG|ey1JSwW@U8 zfI3QQAs&N6>%s2rnR-N%g~vf*OHLTYp*E0m+_{l@oN&ZITNpqzI#BVtB2Y6W{97kb z`5CIZRlt5m5&w>*|H3HxkNUUa@t>NA8ib=V(6y|cctHnz?zWaElU1W*#o6_*z*~I$8%-fi&%Zu= zSv*$}A0M6YzT4_;U^>e;{x8Z&M6EQ!LOIJ6@ zc)k(7Lvecz7VC|RWqiboW_gnVlhQUT5{?!LF3kyfHGGejIFr|ex73=Fx7m5s#_37pZLfHps!kP8n=NCpGpu=W^OgPkO5XV6Kij?Pz94_)9Qt%*1e zElU>T5>_qj#{GlmN18D-6?u+F_T4;Pcw2L@zw29kRtJ8pv03g-R95cc;HHO8PES1K zq9)eAy|I1AR3Vp5v@I~=so;I&CGOBbW37`OjD2$kwL+;UOvtpYS#x6eKZyE%1NZ(} zN4#^nYO~$Bp6mniZEKgUK5tHK|HQ7hZ^80bcjx)W-ve*N*#-r>`sMSCD<=+Fu$Da4 zp)c_`WXojHa*AT9w3?#2K$zGbD zqacUr^$&l0ZAD8|Tri(z4X{w#Jm#IW9?M`_(?=MWh(e!x=vQ)4Gbv(CR zic<^Z;)6zJn`1Sf=ND%^D`h*BZ7y!G&i{&h3u#Q5EC%}^ z=-qNm?t`JMtJ;>g#}@qnhof{wx{yV^XuGdPh4kp)t0qcYC&cZ2b+GSC*x)@wdHT6` z(&Sf>t*q$*B?}9m;}6A(w*Fp~q|c9Vcr$0dDBevL>s@xjk#VyDd9`Ndng+zjS6a5s z36mi;`U3HCW;18^bGSvn+g=e8l5jZ+Q3XJk>?{~yRyMCNC0+3w;kh;uJLFd+^MCzP zh_92nhW)#iA^)av_2NAB8M_e%7buq$@CN#p-y{Uq z<|hCt2>QS{(XKY-nx5z z=W{DnL}-=IodHic9*bi^DTWs6lOXyIeHTrB1OeU}=t_u+AiY8Uj<|w}^xI?}h@|?R zAA)~~H-(J7LD8GQ$wr)b6Y^5*<`>Nb;nk2_je>RY_5S;$6s~ODl9+jz@UmOY=a~MO zxR*-Q+pKIx=mCZt->fh|%=GhM7{CP00&tO>8hYXF*5NrAiDll+Uk?}nI|1zh>%M(e&!>TVB#q*`jp?oU?RQuOkPv*Mo$cyuOfJ1*4c!f| zj1oR=^`xkcO$%iCh(?WUIFL|BurO$dW{~vCE;SmLfZAImBq{dZzRA)^ZeF7Q?#anJ z<{q7xy+s87$fvu0RQ}ZY7@U4HU-dl?jf~A-OG{In-w)rM4A?enyAzeWhweo^`?~Yo z;hwg49jZBD`{7H2^ox@$+M2*I)0^ns@u;qX`K%@o*&!;FhkA$9ORUcA&^-(21d^PQ zjnFBSIq9IeM{2Zk-vzWW{j$`cd8$ga85&qnW-NFT=nHQRIQwpMem1wV={l0jB)$v^ z3mr3flo_%a|7J*&P*r~^vn>#|cPgEm_mztyq>IqL;Dbr1ice^URckk}Y3>pWLnM^) z>6cGqA{vijG5Qz$Ck}O?%Y8ST;#F#a_B_E|aU;_qgOH+uQo92-6i5i0qkMuQMG+`b zQK9@Qz;c-;@p|es$LD(@jjxl9k4zyfJ1Z%t_l5eNj8zE~KNu=}5io zb_6zX>SLE+coYD*gAn_MIB$fwGwCI?xyry<4+%Bh`aUpD70Yu5Rw+^B==NwRz*|89 zP}N1b8;w|3BWRz1ht_lI`Li9aOfH5QC8r}o`JcRKkh#*urv``R%xyHc4 z24I{44ZJ>WBxKb=b{YmGKyciH1qZL+3%HfwGz&*Ylk1MC6z!65v}6ERns-ofLEQt!5! z^QtTchl6nW!cZbf4#JB4k-t%AdyWUVlPhotnozOqygrvo@Z6Ci1MUO1h8T~UjL8nM z<8r%7vx*&K2>6*mogC{%my?%_B-LN#OCd+%u;VU)1jX-~B4gz~w z{6F6vM7faR)I)Y1`rD>k!&|tEPL6}EWqdndEz-=+z?}^!-qy=*_}@JX8JMYS*YPC^Q87ySj~J?8TzCdwD{@~e@wG@*or zU(twUGeWA0`?`y=Dbko2uPbe&-KNl{zSp3pIc3eeL%H`pw4RO3nfhP$F7s{{j@>7d z5f^%7Dvo$XtWK=YDU=6Hz9OgzH|}i4q)=W%HQ$G91gLs12G1QIC1&ncXHG4jjFRG5 zBSbaN!`ug)td3#l`hxoI?^Wl6oC`w+{a$Is3)Sl!_P#H;H$+D4WbHD=n4T+_EqN-Z zXBtFe8qB3aHy4p$GWQ7Xp%Uk;Lp1Mk6i+bYc*Di;ySe!~1h^Rlg77v-$ zVtBDD`mI*{jYq39CN1rfe2JR<%-XXb=YzhXenJ>dKKlvc!J)%!hwzR<%3=4B4Sz3C z6*QR)XF0m z>2q*}o!lvb=j=H-luF`y(nB7T8XTO5rEN)eBzb5w1%1kxu2g<*Xsn1|p(p+M1qD-Y zbyO~`$k~IuAyyuzz|Ol^48!7tRNkxj7SDPBW+evprNQBa2D@OLfh1}HWYGxAHS?|^ zT`zJt+CFTLuC&4HTu4^!HbDRAqJwz#9t6(kQ4OJM^rxqv} zx7QS%g3O^CH^(yw52DEPA^6Z^T-kDmzx*Q6%b`?ZxSu{95Ll)<7}RFZ73@)reHd)L zfaw`vaH9ldSj9zxFI5=HjUz*kETY6C6kY;+1k|QI4XuvZAcR&*fkT1X1Kva*mID&K zvL422fh}1F!b9vsX$ZU3>UA*g#y2u)gI31A1m^Rgrn8^rM936EQQo9h)h&H{VV~r3$JL`-9jRf+}dJZf6 z4z}1?$#=FCasu#Q*zW%W8Ssvg7edxms$Jvx+=iuwS4fxBAJi55sA9-mCf;3F?fU(+9N&b^5Qp9p{>QzM0dFIZ-4XyV4*L8Eutrd$O$9)wP_77U0 z>X~-g``Kqx{Ny&fE8Dzn$XMNWtwC|xi~@LK_1|qi3W@Suh*nMf`sG=7(Lq5S-DaQ# zc5~j{QrG~4>Gy%t`R%UW{?pcC5rRy+D}FuwxxJ!#Y9QzY#+lNfWYgb^si*~QOeD&h z>9lL1s`*PMuL8~R4BaPBL?~=+Tk|2h9UscBUYIWZm?ItbcxAfZyTmg7c~0#8!mWH# zK1h%I{-DaQZi)pA}^~FgALNyCT#-mbt@zalxn|v$@2pfWFi?W z@#(yF;k(nkoO+EWITDWMwhhmY*SQR_SY6NmQQ*R^J%y7t#5^i7Yta?my+=)7(NChWUWJLpmo)j#VUm>Y?DtcQ(>gv&M1aBVLPhXqQsTjG=*m5SgaZlw7-3aEP>x|!O zooX<XcFHx82nvQwbnJ;gF^?RF|t^-a8e%nJrWKkc7Lpop9{q6MVTCv)6WcKza zn1DVzx;prM5^p<3(mN4*wua=RahzX4cYM1$j-nhBd)RBKRH5T(#)79|WW=TZ0T*_h zU-`28O}^WUdUGE2_=zsg=AN1vi`D19ubs0{VPmT%8y1W-iN!p~Ivn)0pw{fRtD52C z^BHRf(cZS_2AlKLAKWak=4QD0-G=j|WAQ(#;Q3!C+~D8tb0GZ=K1LNw$I<5eRhNV zFRq@{IREN-W$)x}Wrv%s`+J_Ki{~4t$;k6+IA1u=Td}JM-wX7km)-i0j3|dw`bWQF zA6!+^v)#S;btvRRgDcPK2WzcQVp1brj~UFwdouGu%DM^ZdD52`W6iEyTg&T} zD~R))7u4kwc6}f%<6X%vJvaD*ct_h&RIF5H^%Tz!vXc4J33E!z%Z(t{gALy-O<3EO zUpi#ua@Ol{ike^l*khtypOu9FwYLEQvw*{4pZT}^gjFAwe@)L2ng$eX9bkb6OfWWVB;(<`gHJCn()&x;(|6K4gPcxh1GAcp{5J_Km5 z+fkA-A;d0}#~Gv_1`-h%Lo#fDaM;lCkEBZ>9|NiPw3>Z*i9yijM!pJ+dWJv%1G2a_FS2C8`Tm#oou1(e_(nLLFfPMw!IJ$0pK-<)MLq4;oQTYfQqv z;1#+<=jZm6-Q=1ml8@}mk1!ZA`#Bmakd-0nm$dQ=q~0!ZDa&h;{+Nim2wW9XoFVUq zudW`F$xyzkwtZoGQsx$_^+nv7(iX!-F(i~I06I}G-#Lil3nTa~f=0_KkjR&ncvyb@ z;nx7Hy96}9)to9#cE8Zh8g{;TWnJrwK_)Zf3AeKF;G6kZe0?NH&-rIkASz?46)VU9b=3);sg|Ij|>KOPGP46)L>{g~VBJ3jv3U z$t@Rd>B=op0QANSj`Q1=?sL@EKeYmdSEOR0R#n7w9 zr61;g=3$B;iDJYzhQK7WKMvC3ti26SGSL2oG5SlUwylW2d!UnAM0 z)xVvVn>V6kVf@#39YJxa<^ESD9RXXoV$F%Ovf}O*V7zpB!4UPLk@d;JsgbJc0Mq?= z`N>QG;yb$U!6ef3?*eO|k@UKNRMEXtq1*&%4LV4UQ1PX7cPu2u5u;D9uRq75E;~7` z=Sw*s!$uaNM4W~ye&a-@Lg9>o%T2M+ZMaQ+x8Yw`ZHE%v_-0b_>E`Te0P*Fr$E=x{ z!Z6@z1F-|4d*`xM@}?KC;egzIdz_Mw=Fxa-;#f|?vV={G!$e^o*F_T zne-%jaBmpXh2>(AAWedm6in+rV{pPE-2lYxf3(qkJx8GV4al*0#P#WfcXy^CbYZF=<2zK`xIomEhQs(4q9$>GT3}sa^*G?j}Z%q%Dv4 z6$L{%;d%}p3Lz?9-qDyLJ%`HBP&t$Tfc~t9@WuQqGEl#20~XIQU?IS*MKimz`pijVVZqb7gA!vFT+ zf!2~Dcbk15WEIvXN7ipVwWS=Ys69&9{K0?5fV55Xi*=~|7q5qqJWF^>T3hvhC5RnZgbbr`SAFs-VVOl?X@p9Q?4IKri0C?4)RZZ zAM*!&;I&>5+`k#+bn}5;<yVh)Xo~6A8ThBNxw=bMDYI=$buph~;QI${I>ywp!zK8gCyw~wA z%({JojdrDNE`OBHIEmk}!b3+orpT_ma^LVC#>rUky37p=5B$63BBgad`4HVNxk^Ut z50YY)@Q*)8OT5QzP0{_#+np~E-wK`EF00eQ7LFXHJerT+RlJ+SPp(8sW4^zRRpA=( z3mmKOv#%Im;*5T6*Ul2HuD@ON)Xm$ZqE9I5^T_hvz<1#nFY*o*yxMMxo0P#pnq=8` zZk|C^;NDsynj%9B_}y4 z1^DYDgd%(YaVbX@ZD%@HP8bE#Gmy(?@1!J7TAT`8SNjxQMJ$e~zoyzRu+eN&S@)&% z$4jn%w ziY3vz*%#F_Gx&XbCx2saP?g#!|A+FI`nul^+AZ>L?XnOC;KU!k^<~S|yTOD!i1}9d zSj)(X^XvGD!ff-!H0yZ%cljy&lo%LiK6`?H+$P9%z(Dp$yAHQXfgrYdEniAGXwOv0 z+xSMT@*9_e;9nor*4laY|3PW<&l5ZzoPFSGv62b|c*#)!?t*ru-V9OP7#{JDG7?sb zmg}{y6=cWd{mJv=FV}Zl6leTZm9i?ld6MM+d)Cn8mt45iiczv@wS`Ua%5$?NTfckc zZ^F-#*4#g3^On{%cG*|)4DGpKmh5dI-n_M0G=|=XF z**cV3ime{5np?h*_|8G-u{Ri#nNHjLVXIGi@Z7O(cXojTOd*FH%IuvZ`JQaAZp=uA zx+<-ObP9jpp2OXb_Yn|UOlw|USz8SiEg zaqA-&-IF8iZt0FIe+NWrzgT?jV>Mai#_6ta)X}4L`et#@*gPA_>)96{y@;7o3;uYX ziTb{{$n0*;V^vWtQ8s2lOE6#n#69YBM%D2)3Cbk^io-}A%c88Fzd-IRIg9;r^ z)3cb%xPs-tjgMGgWsN1;ayskBb#GVPR|hEAPFKeJFCOy7uDmWb90qQnZ19uxGRKS& zhbBfsEI_*C=D6@}1JzYMUq|1_Xf4C*t^vI^(IU6CV~+R!4k}czK3bMq_nTF1A@;(| z#c*O_ugw&W?3XkkdLwnhf`7rp$A={=+o)z*kxT!vSkk?a>%m!&wb4PjG4e5E=Hg%1 zX9m80a~{c(e4h8ocJSRkN$W$5;Twdh*F(A&>S_&yYpXF1y229WE;t1?&K7fDzG(5n zYVw^~ffo&>o=pJ*2QPhb7xW028;^Ag4*)atA5`o`cR9sA(~lpN8-7;)eCGa(lzZ*U zIyX#wyV&4^m)?uT_TA@rBv0xA*&Q^G1)%D*Qjb-aHVhzJDJdDN0ETEtaMf*(-at(PGV#J-bpELUswG z6s7E2_I+n$-&5I&CTo{BCL? zmqenM3kEgENy48vgSYR0af)9WXVEw0dd&_-&DZ?L=vO zgJaxXbfinaXl0-M&%uX^Eptp`zq4$ZMe62&EYe{w+~Xmpbye?Z$LOjlNJ&!z3?22Sp=#v)vMME%+~&^me0Wbq412>^n!m;ceti?1m$J*5944R!wYwCX;Y+%~b8v*-Ciw8J)LDxp zM^?7ydq{GW{#aC+uB!_ z3t7pm1(LQBR-DiqZ>bt~ete}Mfo|>-B<4h2xNuS-R8S@&p@Uz=*uOU}U~Yt2x{dTi zQo&v>m?lBk!=?IJ!f84W`>7`3IO@ku94->1sHk$mfh(*x*dLd)dU{8;b#%*~NKJp? zcG1*hs(_5aI^1E43A6n+RJeI3gf)W^pK-FYs=v|ONK@kt$T=Vd!>rTSaMQwn&rg=2 zk;tN?=umR*Fq!>#anf?{;B36sz(LJ`Uv{3C*txCnqf*Y^7=w4A2HeKywmvqgNmr&4 zQ2kuHN@s;%lS^4xtq_@rRX6q{rXRtTig0gN1uf2usB~K(-yKB*?txV+S_C>tl;qf% zjbK>jp3F_G`VVS_=LaDw2SB=aa4#3}FSZ163!Q;25)z{fAe>S2C#ay6cJuUSl(oIM6p8?rK+Iehh01XG1aKtR0P~&}nC7I?YV(#Kfc2!t@>kM&L%~fTnBNCkGXslv(VNMj6n(-`r;!2Zkv# zO&@)TM|JOP9XBjWrX{hs*^yL6Gn9_n6Q*u%L+K-=RUmW%WZA(1(ClLEl-(mvXRCDB zcvuYG>chG)+hF%a!8#!8{5VfrB2OKpyR&763#SPm5TAfShae34FI8nzb&1_bq-3=?IdCD0S8_{ z6*9m<#d>}_R~dYJQ)O{BqFkqiNWs4eVv^arx4EbqnQRM`mG1M3a;Hbx5(u!C)VLqG z&aI`LO^Pl%A&L8*j1qE^Wr+=ofPBI8a}X1VbdQ6F5J~wH!~!{@3d7IG`)@!{I*Nd( zBxvt;{p?1<6%izc#lm=$Mh@5q*hpLpL<@caviv&=WrU*d+Cgi`Fa#NUAovbO2iyn} z^aE7_B%MO;(2j-#8O_oe!J|-0W=WGifc|Fij-J`d;9<#ZD}6wj}=0QlAag@T0wv!AhHQ0pb~Qs*v%Bx|4voAgAqAg=0Z-;U)ASqlt45 zJh=X0_E{IeSg#>)Bo+mD6Y(e0#Hs=wng|P-faVoNC0LX~N(5L`wVg1E0}cZKEDF^H z-U>w50lo-Zi8#<{oDuGa6cPgeX*k`0fI#Lh0G8n&|N8?fEszTVH-=JHcH!hgF)kpM zQ)J~MTL8!PpDq4hwZ}ivhu|3mdWj!_h6s_i^8+I$ME=16+6+|b|NRyOFYv9q1MhYQ z&;R>BVElrV=>1R8Ir1>%2QfX;c=}T~+9}iCxx7cz-_Fe0c$gh&I==llX`O+|2WpMC zu?PB3EJA9cYS!ufyLdLWKz6n>c7ZF~zx#93=9(gAs`C%3mRFp)3;rJ4#H>9tHypWl zecB~yW4Ey_WuEex_qhPBx{kNJ_uwEisqQ$L*B>`!^m=!dz7EY#2((IX@?buD$r0;D zv(=X5y>drdbkXWS$Mr6r_}d;79c?>3ZgxRM|BwOZU{{mdxe~VfH3Rm_)z-YV*kI`E zi~U|-96;$(OxGD0^OM$Fz#l$$Z>y}=-Fx#ym{6`_OWfvJC5>OqRIHw0rDdS6&t7 zymw<3$~`DMqrGB$wXaqE%>cU!%jCXDNgPk~tzL^a@mGt^44xtpjEdSk2{W;;MA>=* zB35Pl<>&l`!>u1@xZ(!m?Phez+O*&A*ehY+BAHuKD;d?JWq(g3ZM0z6yn-?xLpY)= z{yKOzJ_C}001(hanz03VRJgAI+()x8PnUY>kGqo$_Zb!I-^-ZmQE_i zy`wiv#``w-ZgXvMr$PGOq4hvw+d7}lfh~&Xn7uTH8E%NpE9Q*Q>$Jd}=eifE5k>!? zZ0j?e)YRAV{P+7lQ{-mizSYrdM=Hz;GSvQ-yZ5qc)<*9GQ15HjSzWm*m1#Thy;Ep4 zWreAi!1thW@k?uHQ2H`n>l%6rcmpKL(EVBPDo0-jE96K#dw8O9N#~|WQ0RH)sKi-J z*PX$xqS|Xr;RYv@7d_uKL?rRIZ;7-=@vdR32G=5Oii7C8qcI{M9V@$IJ)QfVEhq53 zSGujt=H+2>*ezwI9tp-Z<3FfXgYc^uu(dgNjy9q1m4W+i05>f1vwkfCG86SFE1X!9 zusWyHv=aq{gZB(W@`oayX%Q7aZbjxvyqSE-BhZ4)Pw`@&(wpDi4ng{rrgg?mzO}vM zmiCtv-_v)!k-Bz|DdVT@uKRjMNvZ>V2~Tone@?jxU`x)(tTZ$PFmLd1pL&fTAieqb!J*}lSFO#=gyCLA9x;o%T42w&s&Xqinp|~Tq`Qv7N&uGlGnG? za)ypeJ-SmhcqnPG#7!!cWGp@HYl+!*bbyr;o3C0|dd2g6lKi#nqMJH{V%zSya5!6P zadQFnnb3h=sG0Tq`{DJV{)?yh>xT@+?=)CP)6YmI5dvK_F5arBxJPh&6TBV^A4QQQ z!>7Q9j56Qz)|Lw38?071u=As5ZrZMH+dPi&T*URkXV?+wd~cZXdA7_q z1X2-iF)ZI+5oshc3}yA!*svD7*|d1oGIE7FqE8!N=0fQ(g<3!luj%@NB3p}j3N_+K zOiuEsqeC~CJjFbpaTfF@tW1=6sy$V=ZmER*3O;J!0mC zyKmu2o?Mfvq7hws#doClQP2icWX#!GO*>afIVbLb!Qad8)Y)-f4o2=DP2z<88`Vc` zoVQqocz7;)9ub%76ZBqjp`3Y<(Jf;-;xaZB`%|bo4Mj{py8aZVMGOPi_Dg9N2Mdo) zOfBcrg^BTe{i@5l;PCBr4I5`xYRiKu{@CpH;THBc_*si$+u}3^@2@4d3z``BF@|0u zcH3I-D=0H`duc;z@ur8w8H1-)Jk~W)qcM$eBW}zw?>~0yB~j)C!foqRj z$~=VgJ`}#Q=)T64A>2Q31(~Mk=GXU9M05*o!Mz$PX0tFP)j6QyPhkgb}>zhX`e!jTK$h8^A_jR7}LTRhwdm|yy%lO4_bKO8?JfKcm zQ?GN{l#V|%fLYDuv#r=0PEL9Iv}-yxPG2pmTp$z8CuX_Ab|puT=Jqu|ZE!QY9jB$7 z+f!dhjV3$y(c2r>eZjq{C;3A0Jm>S7)3|*f7^>@)!!C*iyz=T?&N;jF!EY}~_$UC> zB=scB`YLZk%|L%s?|j`P?wN}R1Nkw~HrucJcwsr6*_z*+|AQ(HuoWp?< zTgMChN~$oz_32Jg7Vv$FKs*ZK>Wx(U$T(y8C9>Yc$-8iedMqd_F5b*-d~G%Bn1eQ9 zOug&3$Xz(+W{ff+>Xqr?+b%Dd^w2dXk*`nW*%@>#9EOC}25`m-Q_5lt6rVbuV!2~~ zrCkj>#1k3yNJn>WY(q;*B&p(j56(bJm$siDHxv!@Ppb4);{yj6;+D)I2<+&^T)s=EfEzN^%f&g^^aLv|~c)Dssnkmggas=u8(L~uT0nCWtQ``3F4q=zlfTrpp*Ol@qIZED$5 zakp139FB2knX?I}arNbs&F>GBi@7;lFV~6goiHnQA~=i9Z2KR%afh%}sfi9i8TxqFVa ze^7@nH;LCftB+p(=J@6KP)*w*v|=Ee(3ic_GG!l#p6x5_HLwy(!e=NewyzxL#t6W zE;VMZ5Z>aUkvnB4N_c~-r$zTx+J0`8vHQwr*E;MG*FjIPR5vU$BnY0fTJXQMJ~fQp zRW-{51z!0=!%P@BBE$ zFCI>@lSd%NnYxbX_ItEAl5jRhASLyi*gjOC|JATVj}lit;^;kSQeC-m_bJLYKH>$# zA6|Xkc>SbW8ZB2^S8_q3oYZ&^OF3jTWgp zG4+x2iKUB0GfVE)PhF|7eGfk8vZU~mb%qRwujIUI%^nu~nf9oNsbxmA({Nhg4QJE6 z!N=WE!Um&N@*)ExxLTXkmknyaX}9E?m*LwYTe$jI(w}Z)}d5mgG(~#`TYisO^BmBv`n&KO!O(cOpJSID{!tNVJBBlri|(SdWc_7o9#yV zQb2R&*QaHi6%|n=fG2c<APPGQ!U+$EKDJ$_kAp8kN@fU zsb*c>I%<|iN#3-!^s}BDXQ<`7NAAJuKQ3?88;qU{wvdU*eN%q6=>%laAGiWN@(>TR z5866~p~ylrRBw6fj4M%$X@DgpMv7aetmwS|s66lFWw;M*+odq2WE}K)d_kT!M+WUr z@itv3vtP*7GvI6r?d-|jC2#H`U6+$x&MQQh$enI$TR$jb-Q0YuX-dyE?0k4JE!8saGlf$Kak`PP{5MyhSleA%ULH{Dgn0|if74UzhBfB{&p6F?uq=2Rb* zfsafoRCY?y9-LP>Kc4=H!U@>8yTS!58wYNpR8ipHKsU+bYGmnVSy-?{c|uPsHSSR? zN~Nn)_6&%26`z|fWya&^l@97u*ls|M=eZ)rjp)c01HXL2>BVySVFByiy7o2Xvz$JM z0yG)Gr<-;jAb01L+e+X_eN-i*!|5ZpmW&j83>?C zHV+aFuw}f-E*lr_I=9^Vz*UC`Gi3nTDD5|oYbNZzGI0r02@gAqFq|0CP31G3*LwOY zuiS@49>{=Q>4A~AgaoW5jOb8_`a0p(bNuo1m^P+EXV-ITwS4#&3oq{&y_=^m>Wy0% z$nL*MMG@i4&UvOw((u96C}0MYsT1nm7E3Y%ziD$aY zX=k8@FUmePB0G7{mFjpF8{EFl<#akGZxa@#Q|e$DUas75({kErnNtKt14@Nu_i&|W zP?-OQJHad$2pV9TAi8QtAPe{%+U6qeKw|`A!uXyh>`@h?Siz4B&$UqhJH(gX*i1j#t8=@s*xviQ|j8D5DRp5&7^gRjC zGuV z_KN=`-uDh;^Die8 zadXe*ThakyDsz8O%@vbIZUT>0`~46@f+PyJBKPDUd7m5@CV< z?%Q8l2)e|1Zz!Cx9~;~r(SMTP|Al{?VY^$OV8Z9nL2|h}oIaS9%lyNsN};Q|X84eS zbi|8ee^8hEPH=yi9IBF$nJ;rRn`%AmMHi=H)B)Y-_|+@@?k;P$yyoNF)^!ioP#GJH zbjs+qh#0ia8M?{q>tC8OHuCUG5~PV5W&2EXZKaSWOXgIe%v3CvYgIgbpuWNQxSwD# z0XQFmA+JMLF}cK$wA##5H~6)zR#VlM&%|PYT+C3Y98ei;Ai!FF-$Ci*(0Mui`$_AO zaVwJ|7yMWzDoxkam-1PNZ7;uHFDZ_9Zec7J3pZ$=Xl(0dU6hF|{5tW=(d7tMv137x zko}(0hzk~ZWmD=WX)C{XqUyRJ(|b00#cH`H@WrzSV`9T|t4x`P>1;0Teh|F-eWY}w zR|t7Gn$Em^m$dTLoiv0GloXrxLrs~ih8`jVBel-pN=+;Lusx_OM%DL(W)e-)Q9EZ zjc-%C`3F_=ermlh;Tj8f&rjh8iW3V;%2tIcpLq!B^Y#)qSUejRb9;WZ6EuV~4riH{ z1lv{IE_PY$^Y%9J(BsEh^okW5me^~wqE}U&hfax?5GlPjERE+93{)G?T+}OtLI(z* z!%x7*ocmHW5IRkrfWmrrL48s+!@)7q5nPqAd;Lh!wNbXw4-OWXX9@MohmAV%?Z(~X zJx3VM+Wq>rvX+mTg~{feK;k`tN4#N#uMe(fFn5Hok)Gl)Y0s+ z$vV=JCU!sAAaAs8_!p^6IdCATuDaJGhVP}gj>W0h_=dI{d0yeE)uF+0L$wCOmHC-A z3)g>`pNXxuWtgW~#d}*t@qP*u`H&Yv+f~hWbe_Rurtz)y-G)()1qkPT!3zlQI)V`$ zU#U&c)T+dlS`yp8l(nWFvn^U|PNU8^qdqFU?1qyP6nfw&i%-=f+O?eg5t2vU{MD$Vf=gRbl*sm9 zrXHdo77^(j@aYx8^>M=8V20^>(VpLl-YD(;B)!t%^>wDC!~DDN4-Yb>WFB4(HEB{G zDG?_tV43}WEmiQmQ5Ar2GZt1V9Wlp5zS1nF@(sU}(Brp{`g*~2waNvFc>*S;GjBa8 zm!WE%?nlPfJY@mdL$~LyjiQ^`l&h8c^?m;izeV1fE+_^(wx^UKR7_y+CnMGR&7RFZ z`@6VKbGZK$wvasSuNBruBT`ep&HyR0K3iXLhHW-t2m=iND!l6dyEAS*sQwy~pH~(+ zdiP%9K;p~7VKyEpgF-;y~~ z5ymF3ExctM~b zOBa!ppjGbns<$jN96NqK=9r<~K?&`yYsX@!+m4Mezam|hiJZ`FYSw!ut)CnCw8B`9 z_2H6zFq=HR#riWoldlsm!bzwnqV@by??2`YH)>>&!GWyE8y9;`c=5*BdkHTl3;0Cn zf;^YHK7=d!AU$w;Z|)*jbSCSzZL7`TDIM$a;LXkzbXVpz1^a9huYe}J==?XIv8-fD zS%{R@u};df2ZrDK&^dXD>@BM*!z-V0zphrA$(eLs-BOv2x_xxmiVl`)5sK0HWFQVzq^%9Js0@9;AXGpesh z!srd^Bs^we%&2Uh?1u;Oe8sw+PKxCgFuX9^FVW+7S+Wtstqha7FZigBN)()fq_P;y z5T0j@f;n%xY4w$e#Vo?DWL`ie@E>h{l;wQf!k7-)2i+(L$ksFO{I(;etIA+TN@Oh^ zNCllZ?h|j}dUK%t*srWll0 zH%2-suajPN(r4-aztTdVi1XqmAeLL=Lo5U{M z*l#a-yY)BbDw|TKTOyXHG9Uo3OQD_e8^4c{Y}F(a?uBsX(!@9tw~ zEhJeTFXNk;2D8|K{AIo|ivDiNV3Q;)wxy46{l(OYw!yU>YjRi}o^jn8t>JxwDQceI z_<>tyKHj*0M4XkOD+uS8Ug0dy(#QKacDlg1?#LXKz_*v?3B^pr^`k0>Kee1~Bu2jW z63;xMKNy$LBJ$nX{gL`&y>nPg(wJWR68@@U?8%?<6k6U52f5ey*Xw2vR8t-t5DsP;JL=)lX(YiVAkkzqdyEz_DVW`7&Q&mYE|L*!#31>iJhct$C3qMNlGl zwkB#5q7%B9ZOcl-l@IIqjlEi7()3=~JN*0OK#35p{UU~wv&3b1V{iSo6MFM-!S<<7 zvu3!9Y4b*&g`sPKPMdRj8o14$^}X?SsUJ*_h(qErc{4q@ zC}0c~BzHFstGAA(Y{zDv!>+qw`gON(lbN`MZmsncSFcb^br$BCT=F&cY4}PM5dDZ- zHq;3|l7lt#8VsIM+y5Z?TKxX%Qs=h)F|S)gYMPT@6==y(cxHreeb&wX>@zFy>Ge{d zeMr!EvVW2LqR&u04km*(!rm9_Vr5tkQeg+T1&KdEbEl^DJ~Y{uKLXcWdmi^Ic)XHgg4z8l^dy6!7Pec(L|@B0bA-Hznym&ArJ>Uw!9|e13&$h@X}h}u5D_pVRsG0l%9{9>4l?eYQchW0bVW5+ z;Ij`~IC|ZVX6;~EIFBZL)Bf&2hUL&%UYP`f$R% z&R7vy?k{621xW|X3Gy^+XP1n01#Ijaat$aVaKEu3V0~-UYFZ-wP1F9fUh5Iz!-+QH zGkt0)`rTRXRI6DwxmvS1HI!T2rzxggZ%TBRi}n&F1_+1c7lVFya7y5LPltRFb0R3j z8g&e|it>qEv)`54V5fiO|8Bq-pF6gZ&oCWTz|EFcc2u-ZS?5nd#>%&JuIKqu}*xN zekPqDiQyLwc?S^8hwD8eDc3;s;4vvw)_aBjdNU%bGWtP`L8H;ccoT)af=C-?18(PB zQo#&mQtuN6$<3*d17N=vK4P`YP+vvJf5YRDo1jW}Tr;C!Uk(uM+QHcUX+;0%(D@%)Z4QKqJXE#_c>d`fap;V)G ztCrw?Po7#~!#wQQa~qmbR2-Duw>Y?h z1nJr3aq`L?yHjejcsh9(-~u8M?0`@{NMwuCS`N?kdqilTgv=90V4WPa6sNW3J#OBW zbcF^SN9=c2AuTM(NRp{Vct6JNN*xPMXgAHcrk1=boHGh!KL${>N?D<1@tfFiYA=A= z(~kAQ#d19Y;5SbJQj%>Tmmc1k=ol@ zuJdssOaOCZK^$`K6^(st=sUgsw{=q~0UftW?5t5no<#i!r@k^?(ts=Sa3{JBiMP8OjcOf-F~1zXa?C`UYr`C|J%^Jr;3bi8AVhg!x$b3wi8c6%Nv^v%|=M z5CM1;Q19$8Qoz3;eFG?dF;3uE5H`iAOY<&lYoKhP0{#j4olate9zuwr9kyjBPy{m9 zfja?rRlwhPZ{-~p>#v3eo<9{>pB*OYABV?|O$<5J{!cgaFL?v(5}3t+M?-F#5y8?w z49s773$ly<=w<#x$?&tnT7_4Km4~o4$WJLk9sNJs{$PJi~#ShYkf1ud){xHBhMs-&&6I7W7tgJqzj5b51ikEPw^k(2`X0q z`Z@mYGD4{#EfE(F#NKQUg9Sip4u=Lc4Fw)5H)cVQ4AH(g`Cuqvt0#5ZeuKodsfcUN z>*|qkFt6bh6A~MW)mjPpg9^M7Yrx%1Cv(;9wlZshXh0q(%~OM>Wu;zUZ2r+M3q=?k)R?TwwHOT9x*)`T<`*~Q< z=>Cs`@ve9oF|PM@Gx`3eC5p7KXV2-ppW`Joc76hw+Bb!6K_B?vplTyogJ>gV&)6skz z&DEmuZmp@7956Z2 zVfTG7G#q=!8+-8~na3|7Te`F+E@9Bi#uam@p<<%q_Hww0e{sQ8_3twdZ}l0EUaxu4 za9{8J&wZCEI`vl5q3kt0X6E$00GU2q!NQafv{`IG$bRlAa~Bx>&fMOEjysVP!P{3+ z8t50VVQ9$HUpmin&xjjPo^0-}7oyP60c|3M28YK3{LMLCnNOoF$$|IW6HeT)Caozs zAVL#OtVI0HWPSI^li5<&vJFkP6Ks=k5sit1?u8PJ6GbxeVI={VPKDfwh*e&B)g+wU zEu_ZyIuMBkXlxc)Yp-*0<6-XgBC5|33%4>Ww*~L{ZHigX?oaP6o;7nznVQS2y?@6c zKdYl3vtMdeDmOU8nVDmyu6#Li)qegKgs0YKp49NA8cMxfsP;eyyCEdpFQIC#8@z_Q z7a43sYE5bv3Fap+rpU)?7W4?mFsVerIEfRh*`Sqm$hN5Ir3TU<=X?aN7I5RVbA8m~ zQzn7L|o(O(6 z*EdI?vcJ}Zt-VXLoq6S*nE|#OM?~AsGz6`*3>vCLA1%2)wpQ>duxKsV!(p93&O+;$LYO-&dU?Vs@!_SRc_wLH~~X->9!*Z0Zxj@RIu`bbNNn+}BcgLk)A0~}0Wt$uNzg$?2!>u1*#=Fovn_Q$NiM|~HAz*50(p8PL zjNsv<6ufU!3xy+?(w#*i-0~0~bbq-$W@y4gyCux9i9Lo}n0~&(a%ov*9y1#XstmfG z1$*)%1$fgflqWWlS6dR@aPGKgR_i6FuG{=Uslsoq(|XiLE??4}#f(kKL~7!1-L})H z%e^b?>XAi$a`z9a5J)Our#2P0lIHYG^BC46K7lL*L`=zjXVd?nAgOEo_ZhED7n8G? zh4Z)vWnZjfwjL0t0)Ba_{z07v5snW)ah*>F#w_|bayM^M7!P-;Op|rMP=+N5ny=)A zghU-C4>C^V8cEDV-479HZVj)`FigB~UhR?)H<9H)P?B@EuH%)mFPuH3Xg6Rk>NQ)f zG#|;zIf^Dr{i+`l$5&|H8A7|RRA9Qo*8Scd_4_j1n)$+4d?5GXyaw)>#D%vqr56=! z&D2)~adjqb^DLWAm!dC_S3&vKD;oZ`e}N;BQ?bF3bdtEyr{~7zm;8()LGT z=CK{x+hqrb{4Zl>m-IY!y>DS=@^HUI3M|uz{Sr6!8?j}bK7Qcx7>F*7wsZ$Xe+=E0 z%A_4^F>uhWOuCk!4on}>9f$ee6jw7z?5cDRnm`-O3A+F}4i`BK75IZnWdEof`(^&p zeHpIdvlNSmpP#8Ojd;>2g# zdkcuK6$|sN@0`Fm@YGm_TpXL~t>Vp#5y)CHjcS(8Z7#?%(pP3y(pj5~yei?%6d$wA z6@K2S@b`>uQMJViIyKyA0`F!WZMxFY`v>L!HFjtU=Rb~#4K<<^1d}8SH-A|LzdN!X zDj&er#Qvl@iSBJn+=FRGh9)2UEj^u)*K0MaANap8%rH{^>F%Ji;2e_ zAlN=AoSNUTmiF}pRar0kIg4u!#?E0w_ZBC}TO^5W7DIElk8Heu{ll(V{8K*WD1Ef( z%(VY_Rm`fb2u%yEo;ht%`yxix^-tmFuahSpolo35LByvfN?&Z^%AikD|vM+-JiDN}*b68xwC-6G|dpPM=1P>Fa65 zy)e<$IY0^zq8-;s<_)16{5=e8%rFTqrE+Ey6}1vob-vTXso^)Eo*($H_Z2W*+ZT30IwpF zJ$oX4Ce!}tHkGt`58s5A1sBg`@Goxn>wN&pLFY63$a0GCchr!#eQO*90vyEnAr-Z$ zQ4dOkb`_b_cBk0}u@s1Wnc(kE>^YzefR8buCj!T07?UQqVSLWS=U}~onO1vSc~pQJ zH-z>kFwfoAG@`HEaH!PU#eC^X`a}pMw7c>ziJT|Xg`c16*aZq6SHM9vH~h8+xgkit z4X|ChpM4bAJXnMDFlyW}!fTqj(o+!-iy^ zu*N#Byp}yZwCEv{>_PNU`uT~}S3#mnE70$j^427xi>|!i@v`YiYqwCV3wp@bfMwg{cGureFDLHu-7h4qu#zIdfq6*~OD`Gy$?q?7Qt9{ppf0_PEx(+)Qg zf$$L^hS?3uV2JmGC!v@o*%4kL`vL#@`_d4@O+cMUh0J6qoJI~Rk{%i$i&aeCK9BLQUrQR;uQN68 zWAn1%D@sp|z&4|4e2BN9LxZOg_&r#8h%CxS&tSZ*KW*hN$U8TLS=XWc_}^-KOxQg4;Y*EpN0f;eY}k}0Ea0W!U;nW0#gAwIcF z25-j)^5rF$zTlK6R1Io+?Cc*@2$p1DrcTbiSE1FQ8OgwHB8?z67k z_RO#vTj$viKlV(`=r}2Ycv$^rhe1`AN!hDWZ5^q#A77OYr#c2IDO#Gm#=yyQ$j1AkC@#``IyN%zw3qa%>V%`t z$%9>47<~U^1@l#~R2f~%2pxA^tdTsGzLM#SeEzn-^g0cV6()*-P^o7QqcPO>n<$OscLy_^7-IGBvxocw4V&eL99HCC}l3_fkt6i>UrILn3E|;H5 zo|FD=z z=huIvRwvpuM@(9zca9CLSRK!PB&PYk@wGSRX}}m2uYremk<(pbXkX^Vfq(@6DzkNa zP171i1quy!hgEDs$-_eXM9kv`^hfPKsNa!Bxc0iLO^bL>wa@hn<23Ugu9f#qddgVz zx_-VSXurO0eyP6o(Lui|5}KtGQ+r7pk2jchi>w@S3M&1W;T|vL74&fGS}(hT?PyZ8 zQYa2qVn^O{v`2ZFwA4Yf%y^I<*fL|#&zZ?*xe-Y&XPuqd(Coh^uVhA8?EMm$rQrF{l|`N7GA7bl z!RQSx#z3Qmyp%tvwxxbis=Vu+#g8XBWi@V${gqaM^(FjuVb=@lC%>pOH6EkKoyB=v zwMj4T^`0$Z)SF*7C_ecpb}$q3UwPAoGV z|0J{0XE5#R#_a6il_J%|nljTY=OD1FCU;?p`NofHxTAdgZd44mbO+2VU)L{f8T$P2 z?4CtwA%cTONI`WC`ru%5FU_#yoUXJfZJ&6KffB=`_@)m$)ONO(_U-$(Ml+XL4=vo0BkO7c_EB0p0-`*GV&yN=@7`(B zD-zsX4| zwqSY2_*d3Tq;4+~T)U5HF)&H9sUvU|Rl$s#YYU6jAc_1Q+Hltmd? zFz#zBX$*UL)eNhs_-WxVF<21(00)SLd$7}h71e3oP8`qz&M5k;^*f9 zOJFJNx=Ula_bKxWV`n$NdZA@JAK{)?o|vH& z(jypz_dRYAVR&)Et5&ew+sNBU%Q^4)wb@vm;PD41lk9a`4ElR!Ng{jGqqudxUo)FO z=bAw;AQ~4SKA@ZUDvQ*?gJ*GH6Vc%xv{O;3`lh%##$IhKq#k%c)86dc0i65O2MzIu zwa$I(s?uwGu?RAt3mjGZ0*6-G<%B+rjJe9Q_4yj3UpS1*EmnMVXr&?r@xH!Xz|rxA zGu6heEqM3_L~LA!YyJHpF>;*|Zuko(@~%aO|3vn;w2I=I3t1;KBHNBML@yilUC6dR zYUCMKBa!oQ(6Bdm_}f-=(7hGP6khF)K0(`?N^Jh{Z-T5QK{m(M2dm*VeXIFI>zGsa zV0UlKx6t#O!y|{;B+8eLsaMbk@x7=>c z|$KmjJ78_6pb- z8f%6>rThXVP)O6=uY&S0so|m;t@b))5pW^0sMV6PVgDO%q^FhEY(jJd4~@>+RuN_z{_Q!ORBVARzGO0KRUX3^Q1E2E;Mvx3K>T@JgW`%=Vvbaq%#)JVp1E2=J~ddAkPbY%iq6dfkO$J=aZ8UH@k2bGc2SWK>|%asr` zfQW(kpJIcV7LVaR-F4au`ub2BSDJS1WGe!QIahPcqP^}60lAC2i*tPibH}uGt5Kg* zH+k%a6LEC5dtM6k+oHrT87PN59>@<^ZzG*mMV=#9f&b282&PP2`-b!*(!_1#H3 zb+&A(QY}ZgIp9i*-E)BvWw}+xXC>-qZ}3uh+1{m@owGB5EZx#;0&14Xk+tCV9LTQZ=YwadyQ~-nMU-G;9IamBgK%oL7t`_3y z7C}ZZIS%alT}`+#!tO&_J9dQ&zs^9KR|t|U*edj3Mlv;r_hQ#i%^I35P=C^+B+t*0 zvu1ijg6A)cE6>(koz!h51xaWHv)e+ zI001bqv76%bdz){?lsVqLqG@ukRZK58RhK_q3vm$ulL`8R%f`61xyAb+E~QYkgVkd zjrI~@A>p#k^D(cThy?({2nUZl^nW+{tqv1o>SFATW0?@6;R>5U*LF0>zcJ7M&wroZIkn;RJ{k+fGrN#MF~XZ5zlG<6C;n?{_@BQKNVqdzM>4i|wuj&R z#k>D*^0!$I0l&zTA$t#F_)*%z`x400{`Gty&%cA5VM97G^fY?vmX=$= z))Se}-jR+)PeYf0$gh~YG!&N&4jBMmP!bOBDSZcy{oP;XJ>cWWxVk-&KDMrJ z1xJRNiwgWJCxoFnAwY#0=KtKF%Cu!j;5ok*#IstI`Znf>N(oXh zQfXPwrxZg~Gq#hp6F0S3FMv=R-TV4!27GvbKTQDhfWVQJ0oS)3Xblh+kzasH13o3A z{|Ra-McsUgW1_m@_0@bie-}-X!qtFuns-#tyy)HXx%3mf;SVpNP8w z*Tx;A&_9bK0QnnUK#6~ChqXZZVQ$Fp{Ljht%FPZc1tba6R}RuEA%^~Mc?|S{>{Px0 z#Q;zIH(}<#S0j|8z)SCx@CYI56Zl%;YB~WO@_{`O5vWnslSuo`0o^#bR_^NZUEJJ; zU>CRym`9G^o%=@)x$S?VN!{*4L)oNS3qDr$LdFP@GFnvDg%_ade*F(aR+(DKxi{k zIs27Jul9(IqM4${>NipHD}7H5vAm}8VGPsBg@igD0) z3slXSrdbIszu%vHc;c?ZN`Aj9wt#9{8hqe*UzI-1p~H;X?LH5eKF*N3s%m2evAe1z zsS3~hka|g)^qn8XR!H<*pwfM4T0toCr}!EL{(pqMbzGBs_&+>ELIhD9DkUln0s^CB zgme!9DN#XEx?=^q$sjt*8o z{Q3S))$|>Bf&n>7Q^7>YLy;978_~zm@9P%&sl;;puc(F}A`>5$85PIPVW=M>LS5_U zSOczCw0@WVHkvaNVQtOYTf~_ISR2rW{jI+tO|Qo-f6|0bt-Uri>A5PaMKRg)K5`<7 zS?{WPwzR5zlx!{Pg#+&V30NhP>BPQl*+Bb}iqFWn!rK`6v^Hs-wF+DgpG&0S$H_Y4 z?Cvq0!$8q)nEL*qmxn7aXfaGL`A)BjL(yx2dc-JgZ%evYXXurYi&c;dgRv( z-=}9&-S7WIhQUUnBwW_}L$KE){TE}4K48tyP>x0+85heJZOSXRv1IPclVToiF?c?K zX7l?G)sk;LC1ajtO$r9Wd0yo2u>hQ(<*Tl!zaeXSH8k-8p2tb4YwEfTU5RdE1Lx?> zynT~RgeAMK?{yP-0oSy{T~4^Ty4Vif#*9?*{BcR-7F9E~>!PNVncN^(!VSb6fSM_X ztUv@fTh-m5L!HYGhMX6r5M@{PUfXZYA3JFRK|!D_K)dP2d5I+CFQhYr^z3)pYvz`fs*+^k>bK0;VwnR~5^AR1dvh|y1a{m*R;N4GPIR6)oZ z;B`4W)s}V{sFCScKkvCgHEQ1na}r#?dMP9%y=Vg{OH&j8KE)$lzb61(o7*5h(D>vW zV5dat1kLad0Wcytfmgz^rhnwY)eSy9lD{Emuw(FAwBl6#vfhOe2np1+L-To|b}R4| zre!kTK+NLT-)K`8?HBwNhA2AFJL|Gv2fUy{-k^naxD9;_MARs5T{*O;Ao}1 zUTW8RG%BD2s$6Q9z&ij}3DP%w+?bYyxg#o_s~i04bcLlhQ}?_xDVKaPl9q`{k>7%; z$a%H}1`h*{`s^Sx2c{8vLK<^E&l-FtKqzyb^czoXG*i6`p^lE*#Jhw~p5|I!Jf9jA zH*VgWXmdRI9WdGS(e|8iiN_uCz=9Fsrph{z1J1?nB(?LofAxk`7X%+dj1B{N%8Oqz zE%SWtCDG>nXf&>_oq3MsyOj&v)EVsDPym!7X4j4j@%G%E%RmV!&y?b_gS`Rra)3jc z+#PXNEPIO2v-)^Q$aDN;?^{M;?ys3-Q)T^si5rOMsK7{W-C3Ah(|??9?ljVn;cp9t zG;H#kxq%@FxU0&ATPWP5TP`V;MHB_Db#F*b^u zq~-gD@NY~@b{sHP|ASXOl8E5=sq~as91&fk!4)4&3g#owfX&zfYCxbmMQiW`6CWIpmS+IJ z0G>H~%3~zfZ>NP-Jfjn+uVxW8DJP(KV@2~MgJ2o}bOWC)3Xp5n<_b0jU}{i9szS$l zh%5LLFk^!PHDL&-xj>;tw z*8wg`#QTVpMkhe_?EwrHutm_wfQt>uGx zi~0kAgPril6^!@?aB^08RKqp8bU)TA0MF;HD8`C?STD|6bQ9e(v$}-q*5i&8`|@TD z7(^3u&cR;6+_VEeZPdhVQIMGW>!gUT)@F|wQg-?qJro`Ey_do3H69($C{B7`)ydxZ zf#>U01_8DXeG4;%sz+BI&;AWzCPSJVUH??53oA2S4QE3se)gJ)7}QI^k-zt+EAGVI z?{=E66wLb;^D{?6ClZ8=Y)Pu?$13!To36oVjLZgnZOvDi;Yh5NZz1c5-Kep5Pb#7( za`DONNS7GHE!zcFLD4=Fvn4*4vcpT9*ILqkXXNLf+*02enwyzlm_)U1u?L8T%V|AP zqTbzY`CXvo&jKmmTmcnB$&>_Oew84z?EB2FmKxC^DH4xg&6&R)#SavYJONHpfxTL_ zsL(drY16_i=*N~O9>Z99S0z_RRn6xk)7uixK7LNAF<{XdwdG!)RWysOT9XMyRrYVWPERNAsh0!)E zy>(#PxcH!AHqzGXwZfOtmZQPWH$|dthvL0??{r(fM}O(-Hcfr{x<^BQh&t~qBC`EN zbintGTF7)dL2&%%o2nym1@rOGsMVAtz8IzME11MY#DvDJaN(vBRvHJ(omTipDM7UF z*V5pKKZBv`4|lWdLFbZ^6!jTR!{=I|pJlHwbvMU-uR-&;eA@UzU?35VyX~&TgSwwC zNnsd7*AYbg0CS{rXCp^X!XW?89A&WioJPyjsM6gY(6j z)5O5=@zj{}`jSod4=SYIO!bSMMA?qYNE##lAHs4vFr zgCtK-xk3$79_<9t-#1KgsXIVesoI|d%ob}VWJIxB-v){KSxcDGvST-YyjYwIVG+*+ z@2#Tz8!|xPEL_bF>SF<|9uKvaeyEX?6DGOdu#2S-TiRXpS}#2Fliq@2J~9+<`MFmBwOwWFCbKqo-ZRzA@}6slBVC z`}ez=lXZM~y~P<+e1W5%gUX#Lc$7VjuV1OY%Xv;8pS;O;W}1ONPe|iE(`d|LA4ydX zJ?svwqrzc!M0A#ywQZ7#dKSTuqU<=lm?R$KSL!4;zQon-(ziaM0kpq6@)2mB9VK?* z)kLnyI@VC_+%x(HN-pdjm9WPX1D=bx!u@Rhy%ja;Hq%5qj+d1!5lp+7iyA!)hS!?v z7SBlO1NsFwY1Zb?OYNS|`i(6x9%ksU6x-XnH4`^R-5T;{Os-#{=;H4~FP6j~(mCzs z>FOnY^Bed^S!|3McOQerEzZSLSSh zepRRca?^58L$A|>oPT=i@qokdplD)0KjO+ut3w-Pak+s7K93}!2*1m#le6_> zUfT!Q7v!$#xpj;;8lFTyegrH&O+)6BvvJQ5F-6nD#Y{H3%Y0M?iyZmZy{&9*qnM|a zz*{qn=p8_!%w3$M-ut2W_N;wRS{P+B1zO$%c5le_18~q}<&C{4GK30C>DJWCu7o*p zvM3_rKD``$YaD7Q8Yp8w^!oK0yL;{||4?^#1yeUxg9IC?BOs%xKpD)B%Yl>IISh6bjA#W$6oHj06f~Yh zmk51jZor4IiA{C;V-W%%kv|vd8%5A+IFR4`QUClmO$K>yzzPCOymW#pC%)Y6G}a7E zgU^9kwH^&9b9j7-7)l4!4FIR$%1?))fsnh@MHc~xMip#NGdc<6LJDXzMRLK)A=R*W zeLxJMpvSmd;6ypKZ*l@0hKB@Pd)*(E6)kDQK(EXLxGN+zMCOaW0-y=J=uH^OPSLnu z0TGAk*_{;#*peroF1HDlZ-hv`9@WZ|6@h)x0Ljx5AbeUu0fs<;Y#mL3$#sG!xKsz5 z&E*D;1Wi{x$<08&qqM_d+4V@Ljh?;VX@*9oxaRy)T zj!xOkJZTe9QwZkn@^{SXgT7@as!Dz%4cJb_lhAP|tC(#VXcNjNMh zr+&c0op+V`yL(AHsI#%tFQ~eXn}(Yo^oJ5-2s3*c#o`x$1u%%8>VF=ahmvit3BEOr zVo|KN1c8)i@FNISU|VgDAmQn$|9Mi4;DHaX==dgI{Iof|=-*B1bH!=Y4%pBL+Xveo zcc|EngT1D4rd-vdw$boPw-?sG*5YeJ>nlGu%9-m&@?2f|Tk~C2qXqcCa9BFu7?25>Ws9xN16% zV#9!hb)tauC1`}s>8gby>Dhg4Mh3XXj>kYgW)7M;%t{*ol%U_Yuf~vmyJ%}yO_St0EW6{$T}76n}~)40G7=5S_5nZWvZcZR=~c0gq!3$zw(W|OlmBS zdo&8jlgfAYy^s4Y02~o$bk6F7BG^Ff9M;`O4?@E)7Lw=y0dnpM5SRk0eBhws#Q+5_ zF$^M0Cb$7V1>4mQq*Q=q6s)=hQaSYiR}j?W3M52H4*E~ZGkN@F?Q7$jG4ki*bRr^W z+~)#N(XhXQ93TeDJg(Kbr<@m1+#zg20iVKK8|1L4Z&(R#!}eThdz9#|Il&L^wb z2NRV`-0i?38VgzqJ<@|5kQmu}iXBhCyKvTNR9P%ko;C;8LsTb$6cx%p&@S*BK1Fy> zRZfV%Ky#ydUOh(sB~e%f3j9;|n*LMd3p5(1I3?%<0KNq0N*h$T`+ zh;H4P#N0;^0f}h=Yd_@=aTD?6F(9BKo@)Nrk2*k|{~tJQ{2yA$DV63wxe^M@dF=jg zuq?4|J}u8rOZ0znS5Sal1`xvk+=J2rnVbK+Dfp*$FF#!i5qvvM)hEEXp z*S~AIwVt6t2KRU?q2NZIxoLSj*UK$^|`vEIL0e z?{W0ye4&NlvC@&@9o~tLJ`O|L_-Wet?DtvFS?)C2m+EE(1oIO>s8yt=cvFfmp!oba zck`=ZP2gk`1>prR>(x+v&UvTf!eD#Ve9cTdDU9i}j`=O7R7t`{oudP7&hqjtvlO4| z(buovhVBA6`_R>x8VoKuD~-d@pnQP>%aJ(&t}Uzl+U`Y9c$#y2d5Z=j$MZTo9B*r; z7xm(%wyaa0*Qe7Kn6$7a@@2+69N4WZD`aLC+P3bY-a}w4Tc8yrMRn;ajoo_(b z|H(cB7O3n+;DK+k!^OP_2`#^X_bI5+LF`B>@{#)5C)WLL?DZVvxgU)B>L>Tgzx4LJ zI?;OQ^1INs$?y0q7#C^>6TD)wt=2Y)hRIe<4O>%GAoIlyZx^kvnbiu68PzXI*PBLR zam^_Q_sU|1m**NjvLw}2$#^c%HuZMZxC!_MNHcT!3~VMD6|}=IH{$uqYPpWj zz>oG_@K*+!n(=&9PiV4li8B?ou!yYVV<2390k7K))hd`WSptt;<$^G5o;3?##Zl6O-w&;%aTu zZCyH+_j0KS#~RtX5!r7!e!p0KqIDdT`ohg#SOz&(M#G0&K1_aZvWv>>7f z;lH9L5(3l)XKNk{+zP)sAaW93e4VX^9k~H<82=Cz8)o!qH>>uH6y8J0Y>uvpa4$SI zAgoKYxtU}~OKbSyFVS)P4;?nonrshiw;dz3it_?$(>{q4Uf3ZipL(KIVo~WX=uv-W zuOcSAqO6=?P3ITehkx}v{KhZIR3f>*K>y9+!I-(`ElrV{S8NpcWwuO__o4T-^(rb` zb8ME9%#pm^m1SZmA2HuAGRT*%M(dB`r7FeJ#~pFK>o!&8<1$$XvIgn0i@Fo!ZX-=y zYnsvguGOqZlpV%loJrCF)B};0tRq9Lo0pq)?lF3&M8h}XgW-0U#BV>W>9q|r5j*5( z5X_kRUBp)S%c8iy%A%{O_Z7S|xtI=ZRyHLkFY?hgm1+TI9*Di_EiNXae5hokRA|3% zw0~J+OFZ%Z$Dpx6-{QVTd7x^zGP>hz9@E?=vSDtyW$-ZkCJDM`soXK3_8Q^t&czwF z$Tn$X9>*QIk&P@j`WO7GW=H+aCNxWzuPRkmpai+}!Y{ohlj)?D*(+jQ4dgXHR7(?z ze+E3en~I8%c3*SvP%wmok#3EVmvI=@ix=C zetovay90;T`W5pF0amPS9~?}}83WG7c~4`4FSA9-I=)HVRxiHpBIcIZ)qaz;E$stS z8qNO8nM+9(Xv3Lx=om81y_$E<#Pti&f;5oH5SPdfBziX($m$8C$)q*LZ-v;tDK^0zcLYo=me!(ZMguKnS!Me8KHEx@iH z7k)>ss?l9tsr&pqTpj;4F{!!OiG8p~dnCxpHXU2g+s>lZ8s@8=b!T4V~$I(L3Wl(ZSMEVEpAbQ@&e=Lh!+le3@I0>(w}2Wv-p4NR5T1GCd+ZaXQ{LEbddJ zSQQaJ<}=qT?z=1fbl&o}QQq3keaT2of}*(P-f+V%Z=R9YEo3<$K@}Q06wpQGeal$U zJ#LsWA#ed5Vxi^HEOM8(XY=hLK;gVUebxn9QKN>v4)DaAn;(;u1je4V?$M7cu_@=Q zTYi3ha3bvZs-hX4VY=3Q5{yIkNy2xp6j)x;nu)t#=XC*xi2TC3_v*yKdT5W`qQSwX znHs5oA6(ns>+UP7-@7%ip5+l3UEbdCsHKavx3CddN0qn5js@+>WykejnzZM#iLKj2 zrg`l6#xC=PC)~Lw34yW{BDL6#*^yyNB9UCj^Ql1)c83DUt&urQnYXb+*W$!O*w zrD>n>Jni+Xd-JJYanSP8#!JdPn9N7&nkb7%{D?eA1nk3)Xn+whh;q>fquI0BNoQgK z`?wryM^fQD*fhOn*`gfyuG4oVWAlAN|AB8dw&#f|e(Wyka|s(3Lis!9pQY;15@>$w zE#`~5wyalH)u28uBxa-W&4gKsWQJyQZM*n!sQtM!nZT!wdN7fI^@$ zUOr)$37Jm1MJ#u<5LHCNdK?%(*h^xGoC6R{a!ym_k5>j@Vr!~{Y}cCL%dlijBlqzn z{|zQp*gjC)$lg9jBaOayv(yOAmTL6@R=4ou|K-DdkLsIq8l9?e*gI)QV zkV{H4UR+xSX;hiWDJyyE%sD%X`K-?Qae2sb|KVka_54FibOw8_PhZbf8Dh$}h?}BnY zA$zSTu#@1XU>rl1mq3;BUIz4X<~`~H zFJ0ANtJfKnq-WJ{ksT(~8!e@mx5?Q!btps5qDf$M@UUR=jpTgD81chSXuKWba{`iY zgv~ZQmo(Is8 zl3+difGr>u(Wfx30|Ac?ArSp70y#J}LCfvMkR^0-kGNC?H1H}V((*ZjS%@~JAj0Vt zj2bkZpbxxpl{1c`e(h$aC`1BTp`r{swb4-M+5-M4;K5p;Qw1mQSW%iC1Cq=&EN8gf zp4eN!r6T%EFc6JXJLH6_qd#`2>P8MTxgR|aW{;CrnQK&5s`ei12gW2|WR(mfm8boR z$#Y@S76C$&7$MxoJ<05MbdrY!K$ilfTc;DaOY#@6xi+aJfX!#1%=Gfc>3pqM4D{6b zm`pv=ZEoU74>anxVgWJEymuW20HyiF)8JPT^+x_PRHj7c1W>;CVcDFBYddu#Ih~+^ z4*v8u2*&~k&7ZcCXcq#=PT*)GYE^*aED>BF_OQfH7WCPmu_m^+;2D3ECx3i5{*Y0? zXzss1h+Q)jECtM?ZV*XPf1dgej`u(P`kxmB!_0pNUButSF8dD&>9nr}YyJ1$KWqG7 z4elxP2`rE5|6Cn$d;hCD|K|n&AxaS+e)>Z^S)Brlpp^!_JGepYssG%|qk;4cN_fS! zg?Dtf+|%9tASvC;P(&ABsqCWFYm<0Y&?aJXJQv^!Vrc+a?*(I2590Za=sgl&9;|QS z^1|8(<%@eZ`Uy4b&{)(zShj&OimX$HJUxh0jpecKzwyL(l>F{`9XZ$vmCM712^nK2 z`=VcCW??ny+_Oy#EMI6gP*FFh_TpiPk@c>V-P}F8ZVOtqfZN*A0_*J)rJo-~uQ3_! zMP!`#<3zQMm;%I)Z!cPtMi$e!8RI-2jGZgCc%bF|mwq-y!Q=0mDSDH?ooeIp-y4mp z%hP*3=-Zs)`iit4<&WR*d@wv9(tlmq%lo%C;~1+$wRuPPA(96p@`k~5QAX5*Yn1Ix z=R?ePTA=~qQlws3XWU5R;W#EPhb3eDt{{ z8g_3M@Nd&rq$MbL<%o{*`F_eW)n5ydAl&}(;2rDI1hb@M*%~H+J?S`803zBC6nlg z=>s!|9_P{2i@#i)mCvh_4sxYsQCBz&Gi1zJwpF^w2)YZhteVJmF5EQPG#;shMcy{K z`)pS=&RZ4P3`0NlxoluDa`w&6mb28}40%=i?aHp-ujvOJM=H>xy4G_MQJ71evem_k z!=H=Z;QP|;OWAN+7r7LHhOw*x>zeOf;ZOf^E;sMVtPo<IZ1>nX&qcJF z?xrBHX=Mn%ZmM75v0J>L$#yI-ZsyXa;&CweATpoNg8{ci|m1AnZ;g9bnyL9kU@WoEmt93HDjNkUz3U$}qCf+IE zQ3O~SH8(f|kkLC2Z4l`73=3U82ZdonMorJucr~1yMQZH)>S{ee@7}*x6d~>R^+Co< zzmYTVjgK({_;{|Z^E$e9+R%c?0X8Yi3qY~aw4u;E(U4F3xr(H&3GeEXdWl@236Cy z3_Y2CXR({~OXOp&YS6XRA*RmhqWzHh6gq+Xw3Dbca^$C+(M1}!BTt>)oYg~*!J4gv zzURA6RSZjA8t(g0)QfbFHII-df| z6CaSqq5}uf5xR1(okFhuGJJ#FD>R&LS71E`@JaM!-e7!K)JO~bm(56n?(uxJU|qok z@Vo>?S$Cw@pyct{wGH#vfMT9DiT82AQ@z>@m6qmUeMmjIaIHiZz5?75iX(}67`vK+ ziC>WE6$>wde(N4BP99x)e|+n4^L}AP55)1z5-MigCq`bb<|yD-G; zM>U}}g;1SQvN?3wqWLwn9rLqP;BQD0T!2<*;CuIvH&^nWW;N7Ww4YR7BwKj>(H(dYnR`SN%VaO zT7N^ZS`DlHa-rdtjef`4g-1EGC%)*f^wra4?MUa8di~4H$S!QU~CURF}$ zW6G6d#WOb+=9qU+_^z}jJge)7BJ+vCi2G}~2?~{~$V3&Ui)i}MTA{Z@_bMibCq@io zf*!p**;c;4*#dV^{!Ovnq4SLO@uYB*V_ftT-#jyXyxF55+Xf+18c(CT*;xz5sqRHOKqLqixlQHS}6crBGY_0h~JIHq1( zt!Qi}nrK=uzxM(DnfcJ0u7O=T=6>SmqB))2bx?BjbM@w-PT z6cz^r6d4;-i6ZsAR|y;`$Wfp@npyX>P=DgGt8R8%ZFGmWx0Z(G`H~fW8>nko=|&3^ z995q&TO;?DzE45x+0cod%j4o*jxvtvMGPSOo9}(q7DxF<`unyti%L|ZgWOy?WoVQUFY$9eFCyJ1m<#*as?Y#coV7Od0k#{=UIE1wi&%*xLiQw`(| z--U-qW}|pDNC63gNVf(B6E>4dNS={Vn!X_C@#nyD<*pHV1iUW` zG)O_oqCLLJuYTF=8-kPACuLddM!^@;9o&dXFAp_`0L#6lJyVg%dE3%QF=XB?c-kjGY5s$C8O+5F_%B785m@mG+0$3IoRyj#ZzD2uz z993In>nTrpDNRQT0_?mn`7y^y_U6o?&D+Hv zJLtz7(rPcwMljrw$QIbXEOX5Ce*A@ywtKiVxA|Y8oZk=8&cCKV$MQGab}x&z$a>xA zeT6qNw>eDsk?Sv4?~`U+Z_)@z(4aA^2_-dG`5?XKwzmRUDc^2eAZL~hkD6WqaIx5N zO(5BDbU#|7B6nG30@3@)>34)A-oB2+fwL5&p8M2Abk2CawS4eliQ+l?d=rW%QBw-D zFp}s;y;TA43LEe_?4fqj_ zWzTBnF=f(fIQt9ctD(_91D7of5WilvR~?oi2c$y?(8QdcYeW9f%5DbJ>8`x79kGml zqmr=7)r^j(f{E`IDWs!!Kdc0rPK{e7&i%CBnXi}n8&Y9G_S_`9<@eATt%odev2t5Y z9(y@%h0E?WOOu5b;>Q*Zr1vg~pA_yFDj7c#$YEP+ni?IwRbn@IQ3E?`>_;EWWG-mF z6>7+@j;clo(k>%zcvg(Z^s8meXiTv7$N0!%>X5IjSi6Tb-J1pn=Da!wrp{81ODywU z;n(Jfzn%Dd>i*0vl61RL(`);tf#cchi4&fdMp{&b4??^iIeA!bJ!O;GxaiRg0I8~! z74foa-xN1PnakJvG!>muUv*ayfoO}`VP*l5jN3CiSR8AE?*2<}v7W<`hbn=n_VE_h z6{gp{vG|5 zQ1W7!x2m=KPn)B5qa%S01H_f&(~dU=OX|f*2H`#vfp`em5WqJ8Fdp^Qi3C#;)xy-xn@B|pQ0t;8t zzJ=q7_+B{&w!kRX5?SsTTxn2Bl<$)KIaO#fpk>+~1TOKYfypO^KGW(T{~2y#7c^M` z2~Q3K{e5!#-jSUY#Dh60c`%2v(Q*F}A_7^9_|dk6%ej${b^T>%3URsy0|q!EJ3!(V zfdCP`edF1q+xS)Q%(J{=>qfx*3;++1$o?EA-F7tS5|^07JG5_oP^wNE%t~Pbr(Q@@ z5;VTnjzo><$e=IZ*n-Ks=sQ+dP?bq0k)1)Q;*yejA+6vAaC|a73#A752SeVi+9x>= z(#s(u55y6+UQozxM?@aPX$v$40Xzh;jlKq-) zN-+Col*nC0`sj^Pmjgs;PegPLQ%TXC8SiC?mj1V1gM0{-Q7rw+a~d!U z2TTlT&b-UF*pTQt`3oGrqqTXG7-E_(SxX*W!}ld^C>YC6CHOdf!v*yx=fDLgHu@^S z;k#_ARRjaB$e93TZ))AQu3vsMT@fDlGE~k*!=nY~2}L zlDuU59Ky!6Fs%T4Av$r87391XoX95=g!>0GuQK2e00AMc2yq$24+He&RMe*ez9jm< z+Jju1pF_Y7lKmEFS2~FHu7D!}a0ftm0N|fgT3!A6>e`YPfCXc~rU9SmmrZt@7eg*- zfeJ{^2E1wDKmwLpUJWH$oP1INM_EfI#bcE20X^}*x%06^j&yu=rqU-BZQ|MhLId99 zA1VX!cJ?WLN}T=osH+pP81NmJ`UA3{fu4;hDYF596A^Vewdo*I8vX%8{`~QuR*U#j z@)LNJfJZ&GiCdKe;e6Yw?y4nN%pkI>?0PsNfFP0tl@e7?n3U?KXi`r zc(5Ge8#vuvM05=35j>QkKcM(E{Cuvyd@G%w!MeuMZX8th$9k=GRl?y0+a-NKQ2{ct zT+&YnB{!I0J(t~RzgK>KCJp>RO%!>EKbfI8G7PBG`Mu{o)-mq^JSD#n6yNL1Q=KdH zM!#%Ko+Mp!=`H9{qxm}hW@|ro439{CX83GUaCr3yS&^}DA7)TxCueVJKVfS~y&&-* zehk=goF8O-Q7L{7WX&WkQkl*VzkY;=9-^{-*G3;6We^CgTe<2o zy(cBG;_Ag-I(Qo6dBl2BzAR=cY0<-?E@AnBLT!#!?#WQ<{0F4~ncLKKH|4ujh!`R#J$e12qTTpV+(Ec|hsPBX)vUu4UYx)~>;U~Q7 zFB}|ez6p<+s6?3IO}Nf_gvOXK2L4rPZF5{3ri}2hef)Fyv0rYe`to_D9w&iE^>3^M zevgQ6$SWD?WKGQnl!y%*IC{y4c!NrFWLf-51S8jX(k8zm!2=CZ+G#VNqb84&#VVHT zDS0WrUlO2YyDZAa1ACfgM%&iNi6=Ue%@Y(wj~c=^Of(LSKx~l$p0P}z*t#YoV5>=D zJi5QnNPbVyZuvu&$tQ~^n>4xbV_wkgvVedEW|4CK8mS@VMQPJ_L7mNWY<_X+zF8(} zx>I+u$sQ~JF7(b=X*6UQkxO8AhdQ;ZN3yKFW_^VG{n9PAzC&j(i4cGzyl_aAXL0V+EiB{$o8txApS zZ_pimzy;V7czk-UOfxZDewr2P!$bmA4!u)eYkjPzS+PB=d$VTfK0jM!_#mf8!bV@6 z)%c2(V{XgP?TNS61iwP`-K;fhLm%FvkXpF+>(O@%ZOfo@zN~t5S8|2$foi3Ez_PTJ zur6etTk>+CSnQ~T@SM*|XRzpTg;%1X%GZ^Qr=HNs9~_(Sq)GvOJ8k5oVda8!2G$^& zYVy0mWIOZFKHZPu$XRyAmqB}+lq;Wwa~>TUyHZdzI5cm;9(lbtOm~4uyb4^@-Kb2fqe${B> zu~>V9qwPnz&(;8m5Z_EkI%RxnCM*^d#02NRS<}sJ3O3fABL5qrmF9z_6#Yrn-6xpd zwy2T*rN1=CpmERx_R&HmV(Wc^v>)6zJ)u+Oyp_w!VBM`=ug{ee{;WbUOhY`#4 zz5+q|=26v!*kz{sF_p7d`J+10xltd5WW>ZBg#L!qq3dR-`QMA<#q|#hK$U}?$}S9w z=os7P-H4!clo;|ksWiyQ&e+OkQM9;l->_D9FROtupT@kDZH=dP2%QM?mO21?oxTs* z$2(iz{c{WW&V8#Hf5y7X2dG%NAm4<+-u0$6i02MHG(b`Y<`i#f*s8oenPlUc*)C>& zRM<0g7?Edzcs_v!=5c17IKr>Cx98OFMYoq7$_Y z?=}6fTt}HceKNVmRCyRQ0H3*8{ObFVfu^K-UZPeMshZk+^-a{$XOWCb+N=V9n)B1r zEAIrX)HoAGty|B3Ic}=bjhLqy)c~+gw+7%1Ajvk1F@(&~5&fj2=;x5x zy>IJgz69nYR0rXRucs z@FQajPm6cY(>eLT(Vb&YsFSN0#+`(S0fHG15@fnKW#Si$dzw$wg&TGni7797^*0+{ z?6kaEkHh!q<~By(gpWfj^t&X)fEsCbyyBYqWT94CyJM~LDfX!Ku8sro3y&erwYEe(XR;=bc|9(kM2?fz#%JtSC@@Z?yc?P^XD*ZBi+9v53rAi)M};I4i%op{Bl}cllpV}WBM5DC z&7_gNwpRbLW?CL82SP)d@$_KBqj<-wcS+Z}*9n_=VMmX~r)1!8b#aCp=p)+2=WBU9l zUhdtPTzvxK;JMU~1(eju&*&k7U&dx8`S=oH*Y1_9 zasY6~8YSmz**Bp4a0Mefo1qY4#e^hP)J%xuv$Gj})|)q2%inR~1&bN=+cRQMbQjPw zMMA&dfy25u-RZlE_sFQx9ppA!K!5YJ(t!CwiA!G9|k&B!@#l| z5^R$wlqFE-^fLjCvgsAUl48MRMxV*36H-HaH9+Oij8WGi_32PMOC0?H@&srIfbm$~6TQjukQjjNsi}IyS3XCE2 zn`z`J;Un0V(fxoPA|Qasa#Oi5-VcgD`m;2X{E!=1@bZATtam0v8HB#20B94 zMh!Q4+8sHI`d|55wez6Cfjo|26w&dfk*Ai#UbC!I-2@}!44QrWXa%nIUL^eux;V67 zGjuHByI|2By4X~8o7)rRAiN^2;!;7?=)pa9qNMQ}Q0bglib4TDK|XT3a!;1lKPnOU zVO)hJALh4=*92on=kRur7NRTPv$!jIwQeig%G9GidMaau2E-W>Qp?Q`YD{^JN{EhOi^6B8Q5k%h=XBq zq8z|;!=Oh=k5m$yCvkpzFV{o?+G=qvbhV>I*5N#z#-f6vI^K@IUa3)+G@KV4`~kR+YsJe>kuJN zT?H)1>Lo2nAnVYvpGr=$8SArG;FG6PBQPqS2LhH*53+H2s;I?U!*|Xn1(F2L0&JwA z+ylu*d4=ObqKm=>xit>JQ~=EqnS`m+SWy5*1m%HBMA3`lUQ1<&l~`5 zo<9c(BX*fqPN225HYgLrj{vbPXf#6rgy2iy)d*;6$x1m0Q-+A4G+asT3BUdI&e+5g zDFBTCe{cZU(rJbYk(-~0p{h4p8*gAlfnx`OAkzE|P7`UlfkqhmI8BQvPtJ{v%a{fd zZBz4JTPIHK8&?3WD4qrgfr9PT4lDaG@~<-l7=V2b0Q(Om8qcmu)vPwJ4_D{A}(YCJ5W~`q#Pg$ zM4Ab)%>*78#LtmvVoFq7chj7?f&x7}boC#Pn-s8AqJ|p482TX71+2SVAK(zg2w;>G z;Eaf!5)p_D{(sD0P8~(1i1(-b)6@RjSsN6TBOrO8d;i14_@~7_Wo7*DzX5^&U)ltB zHh=;D*8_n1IZuy-sFC)90x+ikA0ZXgz`p;FAVM45O+3c{_QwBo_T{NP#9ILE`}1!i zw)g+>LqrXT%e6Ue{5Ae(Ss>>6^cDX{u}o%5_83|8kSI*RJz;CRU7zq`(id+Jx_how z``tXMC)KP^bg@9!4je~#g5!x#=QuU=ByJkWZ-C$HzxW9cQCIW-z#){u0TDm_p}`M` z$%rEGf7RaqF+@(;Awczax-*bPI2E|ucQXZqwlglM=< zClC9(VNKP(S$l(ynUaYm3&HreU-W~PBz8YUA80s%iAr-F7%bJ(ST7&_st;DCYm@Bi z2sw$ohfsVX3wY8Z;JSX%+;&)=kf0K(uGD`eL>Y=8v4?koPleq6M;Op;{rMDo!}tKq z!w=eL_%fE*oNF0Iuhppst(`RF9T+)5pNeQ`JL-AhczJ?eGme3o z@h8PR29rykoBY1rO2TtwCAw;iYCw)h8Yh}fpkv)E2Iuv};6174Ez9=pk>5aZ2)MYs zU-~yDj$DsTu3q~Z=SDEp1oWtNrkBJ6DRZzXvVcFKmqC1O1DDZTTAg=s@wP$jrTw_^JdVNXq?6>knD-2_+0!4wBmZeDiNH0>kpbWj{NFxRu1L@iZ_M2k!PH0h6cQ{;IFG2rKH|)fVvmY-VIY(8zbE#CFKj>W!Gx~w^1g6+L?{Gj zX&NkKS*yMb^JfV*`Z!XQF=2bixYG=m26_}njUn^;^3b;M{*s(+zT2@sO=?pI_;1nb zVKKmzfy80(+wxlFsPepc-a8V!w$suPXBKr%7w!q*%%YG*R`(~`?T&MP1*XK9g-j>M^YJ%-}+ixFW{jI19$&s#e3Wvg|a&#aMm!&%OaYGt#h5b zXy)nOc1z*qu_YhPN|Pe?F5B2tLky3DD;M8>602#cW8`r|ZB#`=zWtHrw{^J=CMRi` zYO1vHD$$=gFdeamaamPUj*D6w8*Hd!9rQJh@Zq5d3AWPWE9-~sz>v&s_5{U%WC8@sZAa);Nxs8$EfME*e4V3b5gf@YiL;YFW*g!`}XR2ZO?hQ zq~w>QUY7~7AcIu)O0grKyzgf}-MJf%ajsHpg}*Hh**$MDd3)$H?cpwbN-a?k%Qs$_ z)08GN>zgt^Q_NHTtJiL@XWH(m(CuO-pH3#eqdU91#TqULgcvh||Hp-riCeWynsFXh z4V_PB3Ts0~t69aT%ne78xms;)9&F4dY#W!g1wDbQX=3;d!p|`N_7nNtt_jkii7G#p zVU6_%c~~#g>!sHsZ^VnO&TuM3x&7)tT1)lm$+_D)e^Y{^n;h?8RjSj>$XB$v>-5`C z{8{aQ8e80c_-cUF-iKpZsre>1HyQnFLm7#laFA+cXH^~TspdP{{PwDgB@#Ip`(T@_ zf6j}82PuVgdwp_9sA#}QV?U%D&9rba5SC z6`R_AJsvfV@!seV$2>pxi3<^HSRa#Y<~=PuiFbvYeh^?WTL+`UCF!qr z2(5*==UVuQG(Os6;Dkm96sSRVkrJRIoE`KXKPDS-1bn}@SV|T zL3p?5&QE)ke`$ta8E^0zU7$Teso&`i8@lcv=ver<>x6CF$=qgGerb=eUsB=jo#VMg z*z>vypaiW9vu}v?VMYH z5ebBzD#fdGqV3m1vA0vMuDi&1)E2Mrsu|XAV1=5^c^P2LzZR ze#L^?1_&=fNdZjVi9;1INyrA%M^X?OH|7L71xE6DtQVi!wW6CG`H&nUBb0`_Q4%VG zXv;#rf|9UsK;Hpt?(_N`QZgHvX94vVOiod#U}}U-s>;ayAuot~(9y;M2P^Pj8`K^^Z(^zruY@}bA_H>)*Ox9VD3F0-^Ky+9MkOeP)OhN_4;Nej9Egm=pG0 z%meBRCveNwY%s7s3w1qPRT1!8?1d11gp;z1XG!1Q0RtX0jL9TIUPY?}LTBQ%Q3V(a zAp3PByEC2eABYu<9ZVo;A?9;=x>~7#Cry|>e`ISa=sRq&bY=^RUaxa7vq=If(~oORQ6FFLC@R=+H$cCPB1duqwcFM*~?m z*b}`tC!*UzYmPin$mQr*U_Ar`%}TZxSp}UrNdXiILfKS~B}y*1kv=6v_X9(V^4np+ z?&k+jyOIS?7h7Ox4kmpUR)3Hz<^q1jZD4ih=s3KK?4Bz5Y{vt8W%LO5J@A0M+gJrC z1q9fYb0dLGB`!4J{T3I>I2q?0_;)IY4?Be;fD!;_lpuFCMm0tWsFJ6^kj`>|U4{Oa$iV;#8^%dn*dVrNf>e+o|e`k?EB=KJv_W#_;0cABf*#RmdcX6Tr z`;v>v;eRKKxR&j|?}odBn^pchSj4R)|KA%fDFM8Ipx}QRDoPO4S+({zUGky@`Ok#$ ze}vK(jPy%Oz)13#YkO`G0Be8n~|fKmUwi!%t+Wg&#tn zr)}x~uH9jAocT_+Y^aHWT}LB{eivv^#xI}K%fy2I7x+@de#P0x;xGNj%OVqDN-IaH zTa%;)kQN0JX3)B5HqGIzcby7S$6s@I|w^e$uaK<>7UvNv6+d$OCJxT zR;VXn=>_K4Mv*tya9$!8GwTbVtnA=Zuw(y9??DF%8b$DvfWwj*_mSY(1kw;zkOm6@ zK!S?#GhoeyL%=8@wfd*M8s79#iJPNzt`)?29G4)6ssSvdzMQt1anjMt zk4dIW44)3H78J@2poqQE1n^OyJMxiMnd6NYH{zE} zJ=Uiy^jn$X+yaToTmh5G=BPO0s=6t@S0Pv+WMB(8%iJ1Mbv|kL$Oa#C` zpwt%R*5*sAV-yWeA43_fHGD$u0NJKtXl zU)HAM$sf+oSwh^GRWz1ljbW4ncIv1YkFAzQhyXAl86bceIB)CFYN7HWV%b=Zm-1hl z7LPUfr$1f6$dTR~d}!_52#y6Un37Py&?{TKU+5+d31f)IR)QllGgz`RlP{d0nI#Dv zAt1|x?NRq{a47}Zz=z*!Fx_4oXxs{Y87FK3=F_^a8k7)Pm8;p{0a(by$dz%nbr*aD zK>q?}c=$AV{Z`yQzq58aa`_nVp@Bn;u z8Fnh_+Eb1RBfoRs< zB5TO=B$Pb2yN-_3YqIJXD-j8xIzVE8SH>$Nq%Z^mEVhO}WhQ{?E*8YQT!yl+vvs9I zbV7&bAN@8Mu>SNA08=k@dUt>$LqTmG(CK~XI2<0luXjv^+>rH8uy??miMR0~AdWoh zs?_G3n~Rmx(T_2~Po)*@AkX?o-`-wTf_a48~y(*yv0)w>3KE<;bHzpUHVf ziJtjAfd6a=n9d)=jpe8s^Ct|Bnt}svR0`g5HdY_brpg6epQ|~vOoA8U{{us?>KY53!zn}{u5YMB1F-I34>fhZ-7i|ErH&h zQvX=UF9R4xsRX%*ISeC3nf%EGX5t>3$KvKbjs#KzGIo%}L4C+f$s<7(<H^|3RBG`qF|@TE7R&UqghsK^6_6;cQOWb(@l3zcduM=+#yXuyl3{ZQCQpA_e-4xVxD6^Rc(oEJrff0? z+o*0D&T?HHPsGHmjLIQ9^)pa!v|Ovc*eEIWnK?CAbdE9RWo8H7>hv?S|kNJuHV? z03%iUrEK7U`B&?PD{LMC_6$*w%|8$W<+mlfI&JqfS28n1YJ!Ryyz)2e5PMaMgq{#QQ;VjIy#ES!a&C`mAmG)$E_&fkg#e zB^+mYc`HF^nhk))fItWugkfCy3>16--`?KUNwQYwnH$D2laelhatR1&K^=vwVS#}T zxa5N(04LDemhqhiI zwqSq%Ta^K#-QObYe@iZ0Aq<}Rmt+R^n<) z|AAc9Si(|3N^7);n|o5iQwz~`xA}g%`Ei_dc|t?Jh;G0W?Ni2t26LZ2Q24RkS@#Iz zA6J$O6bA3!&Kh`|R@EKfY4p_NTrFUnQYXG&I1X z^K2ci8>9JzVS?oHfQD3md+n;b{ihsu8;|YDvZ*JlCqq7XcIz#oTCG;fnF-;6i?Sup zES)%4?CS=FW9vUa0o2@pJ$ttKQ%Oj zhVKu;B=)Dql&^2gt^I~@?!@IC)jC#_RQvDzI>d5~aPmuLMK2-PxATFe7vq)fdXy&F zZEQ!34TCJ;1ZBWx$9WvH;>8n1^I1U=9H>!oOTS5_yR4r&!|wVo-Z!eJAmV8aBjMU> zST)Ma{eb`RYV~`C2w|k(Y);b7>xk-Xe+x@M_My!Z4bFayq2JGNaFf#g5-QO4sS-|( zQ#yErg_cy;{Bh|}S*>!UO3kW`IX4tviX80yWahu~6gA`i|J4FMwA&30z1Aq-|YUdv3puR;#owtWKPgsiY)a&`A>hq6qdGnd84b|EWSevSBW>#BItS*y?N|3LiuCT!Q1Xrq~0 zj~;)W>YtZ4-fOojMDB)J^0pCfxg`74ejvp83!#%ypR`X6XTQbsFTy5A$`g-n=!3Dk zok~;?4^)Ifp7BvxD+lYyMVI#kGl*LiHwShHJav|$1!xF(w=WvhY`hp; zOd~E=?;h|8g9YHaqzijwX@1nwey-j+9klLc==g#qR$eGzYEWohd^lvz$p4YQW&cjG zpVKI(x{lJbIqAZ$q$#^5n_;u#zANLJwLy|c>zkZO!)5*$FYBL`i`T*%IkM7It2lIY z29;jCF_DmobM`&8u_2x!Nzs48SJhi>!eG4SP~s$HZ{aSP9rb4ExdgUa;>#elL|dqb z=#?nJ2B+*ZjKR`_$|3{PCd7%?G~vs_cl1+t4L^@0Adt^FL!g?@j?68N5l&kN+1Jk2 z<+0=#RiLJ1r*}CMAOJJS&df9}=bN!{G}P`Sqrli9GZufwBM8B4U9fOn`;ZYLZD#(dr8*?^I+x+41i#JXNdi$P&b6#RT)gw@j=|AI3Tx!=o4HU z3#R@IG{oN$UHj#AF4KjNbO;kl@ud@`p_HSClY@k+A?&#e=<_uXLWoF2<3q}~0hBgJ zw(0aG;2^X{Xm!BM6PBb;1_1N`14YU+G_F9g4n>e7>P1HUy+}Hp?R@iZc~ilI$|IK8 z@M7~gkAVd%U>4wjQPO)Zd)c|b0s(Z*fSjI3?4&OCB7h}Rv^hve=$sV7;HpJ{gMk35L9lcTY#blTdfRq6 zH)=$3l=Y|s;1VC0st*F^elQ-!Te;k_Umzk>3*Gb<8bIlP+Cg%Z1mzNtiko3ptDb2q z;ir(?10;YgPK{}kEyw%{fcK~dojfTE{y2sxiBXNjF^Gg3KwoyriLMR+C@DrpO}MioT5@&m4$|I1}PYJWK0`Z;|I5s;Oa|4XQz|D4RpW zeafGrg;^DBQ-D`! zcU6U~cNfqZfTW~-t=N;rD}PsWLPQHXX6OD1^Q>5UuA!W08}zqU_;!n zaFDAL%o(iTVp9zYmB2RtT8x}fB4su$ zL_5fA()Fx>jj0Bl#+_LYVv+>U^6~mm@Q+*9hivBn1Ro+hor$A(z~G1&7O=st(KEsV z;EbA8fDv*-ScT@pMwqm-icn6+N(7W$29`N~N9mW+Z~iU1frJKhPPTZqIdt%kz^D>m zMTPw;r`#3)eab{E2Rlwcg5H(uxXgKI99wQ@D{10R_z^g3(!r{9Qnc_ih& z-_Utr&fJ6`6UGFolgUXiAxJf2K%tD4IDH|M=H<2Jm_KN{CIi9|fo^ zw4{^c^gc~y0MoTP_50b^^SY0G|aHpYty-2>f2) z%(;#pVgsxp@ay3==Wj0s602$ceUik*`(7Ws5cz;`Ac)+WRLJBhTK{Imr*nHxh82tR z=4pMVv=b_&LAzFX7W`|Ny0#I+l*H*U@XS$GRaPU+xx_ndIsk@Ygxm!19#+ci7UbdU z!`FNHy)10_rrAZ6FR}x(5D`R2g@&_EG>MA2FcvEtI`6OFqzfQ}X0kz=CqR=Aa_%%| z%@gxZ5I4xXW#<4d{0;HCTuYJGIx!cUs zwYsw;=5^(3JXg?~RHj*NbAslJzUR01Dq&3$kZPW7Q{j|P*kL%0z+IGKwze}9FL^p9 zQ7Ij5&Jnj)r{Enk=ciQG{jKr0E1CEc<5GS(tC1~hbOJ>mHQAmC{A9(Rw*|gK8F;?6 zU1Co2@1Iy(n*aVO^AYqP2+guz;Xe?v-n|XeHg_2T^P_#|gAb(!M+IM?leeu>MUXCL z<{>*1lp8=2(DAfku8x!8=qTcR*33EN6Z{!)r*I=%=)npp<}1y~evj3m)mE~O57j&f zYd&|QLd{?Idn3D^kF5^MvN%;BJ8X0EYGC*R8jjqL=XP1cIxDXz>$0=61+zr9Oo`F9QMXB$9>yXHR-Ga~F;HaXYB`q3=<^B<}n zvljmRL*@DZK#~&VH*rNur{7Tc|FHGree1m60r+f=lFi=S~~*9B(W_`*qO)T=o(vKB46m@?0i@sar{X z3eH=)0f7Qk;j z9vR*n-@Gds6!$EOiAxid!0X$3iXZ0RRq+HnzNee>B^%AymYy12r)`sL@9WsK(qxEe zd{xFMnGp4Je4jN&fA5kHO?~iETMj13YC)FJzJGH>e`nUhIacW#|B&sfW`uSlf|1fd z1EF}|2kTByDVgA5^Wv5A!oc_yj~@ZeEkhd1*~zV*aXa5BJ{{34D{+`v z^$_G4L&{-3{2IHTvsMAy+0vVCY_so~E9vz3Df8Q%!sRSK{H;&Q$oFCciU&J|3uNDu zRfU3$EEAkW%N_i@a~Fmz&^S zl&x?Qv`$zxHfXwEQoZvg_`L2IDI#HWtWC$~sX$*+Y1$XXm~SISSFgX(99;Gyl|G48 z>y<|n$ur|AWvA1@FPJb#6Z^5vZ6Da&Wdd;_li|nfJJR;C$*p6$EN#JK%TIH}m)GpNtho@KTQ^H-s0$cW z-1r)bscv(1Ae7B}KPwwO5iGYrzUi-)prHr#Hy?~YX+7P}g%9J5l18hInK<8s=E>jO zzNg)Rt~+Yby!U}O=F0QcNZC|38P8Pv>pxJU2X_YP#EH$Xeh;J5Mw%ye+dQE;_NIE+ zy(y{pzVfAg-d*;P7|(Ij1$U!=ASWaJGni|Wd9_b0r!PN@ahVUVR=;W*!0wEC7&f-W z7*VDYPrK!`p|hnNe!269>CN?;96Q~C-R(<1GDcZBe8|y}?K4x)_rr?HE9=$qFICr{ z&(#< z85-V)l|4I^`tU~nr6SQ{=Y~<71F&c7%t>}sqNOz?5yPw}tu;KF1SXlu#bO{0rvtrb z#C+K*&H4(1>&xZsoKg22ue=J|PhG*GpWncVU!or+e0PPn>By6NoR%P^p^7mmcZXHl zua&X_-BZg8zGR&UHS47a3%k#zgM#pxuZr~BCO3h}@{H`*C4*}PPuo1bn8RG_`ACo2 zJzZBgvj>vTNugN!#Iu4T_WRNrHf9|M*=ZaRQDpSu+D37CWdZe7A6GueGE)I-9dTQ7 zp}j`#Eh~mb%dHL;6kBG5M)hOI~|o%3+|Rpi!Hv&8z(iNY}nHV7rm(d1Z4Qiho`!tgxkwkv%ltNEe%M4h09F|jBJ zbkkvDhcdIJU(I;4^zuXK?~e3!v%86zrB_i^7Pau6$71HKw7r83HL*?y>(tLr#?E+i}Xr>6gEI9=NiP=A3sn zUu}cIjD25FFJ23_>=BP7Z*gy7;ZQfWe=Qbc#}wK@eg z^Ge}ukpz*@TT8b;GKP(yVFsgzxADa{Hco67-{74?%|_hvc`ejK79Cf#Z|;9P$V*R+ zY8ljwBIY;WOnKr~b3x+(ReLNk#8@kI#-pn0T)-r4y0o9$5TE9tW~)uN9|}0 z{toG+070e9$h1WO7!fk7Q&RL`OIh9f1Q?n8WB-Aa_Z-%UY6J_A$p%66vsiNZl!^}T zxJ(NWxsFkhF?|0CwCCIaM8}+Ynvoj; z35^Cusj4cvOWEIY3Fdd2;KC`s%`DT&jpqd~5Xvb~ipokif)atWn^hWjMJ%m0CD3@6 zoYw1LPg(T#Po8|e^w`|aZ1`)y50SH?$wqlicgZk;$jeY7N|e0sa0U?=h!a#SJ8xg7 zRpCDaZL1EjKheVfHIhGT_TJTZgo0&}WTRI#rU&k(Md&1JY#yI{Snw5>L8uc=a5gY1oHPwxfp#6*@Zs+{lrx@+efnVuUBTKXY65~MbAPtGtafIM_dXL`6hkx5T` z=OFz`fhVZUhnd;tvWrd`1-k$2$>*e1@y+Td{8w`9~ zARN*GEJbV3XM3nqad8!;fE0g1}-O^&a)jm*}ZrX7=Q|Z0r3Tb%!UWz!x7O! zW~hZl*8oB$L?K`yKt#ac8nBi$I&(ql3SJUGEQs1sDcmw<4UVQR+CX>4EulCQ5vMRX z0n$zZ!~$mA!1jmWE9M~~?8ZiVG#F_w00$LOE&KrzQhc=5eGtISc8nwX%7Pt=mpTlB z+Y>Ga0;mTf%&t{6@aTNa+XY~4Q-ccXEC4o}8hQm&1>{8b6!d~FF1!-#i#=UiT>1_! z&l>_vNr1`+5HN+b?&D-sU@}|>rq#F{NM&H(axu_eW5;Q;E)W+$d;(wzSiX`j!ioXJ z0}{(G2GNN*e<#=f=SYHMa^WV;IDq9}z0$woE+C*1d?*m%;U?i=D=wzy7qewB?fx$$ zghQVs0L2lKlY>*<0UZP31)K$_AEw|n0J{E*LgDWG9f$*VLq7m|3_wg3nTj0OJQE-6P;es7MzN*cykc$;sI zcH7wbHhV~oa(A2@o}g*Df5P)+x1Ll}C7k)h{{sQERFzopT5kMLS7US}6;{vN&ASTT zgKtc%g*$GU3L8XA1b~DaSS?bV4*3D2#R0DuJ9OR{W_R^@Mk(UU%A#kXf!KNg@c7J^ zZaOw22hn=`n_bdHWjCQ5&f!lu!?OVJ^TCGu1we-22PuQ|T<{E_^atZC79XS_@9Yk( zn%%1~r+7#*Rq4%@NT<8BjtBz7_745g5Sy1{AspWqpM)!_490v{BI?TbC;dcap)q`0 zqd~&AxPslm`{S9AQ5ebg`!g>9Oqkg-0Bq-0;5t^gWS;pS2s9|Jc`^42wmN1O-8?bi zV~gEVO&s7;#Cvp%gLZ5}kRl<1@F7w-eRY=+ zyrb0-I{++iEwD_t&G%d3DvZN4Ek1tiPzkmPGeon>s0{rucF$vNeey7XR{p_Y^E?&@ z@w`R)n*Rg22S&hV1}7u*g38UoYam4V;Utp%N z3STWa_bwc9)$c#3p5EGuIKQMP;Q&M-4V?9Z<2<3E$w;n&m145*MV!Hp zrzp!QS(VFf@lP2Oyo}}ooqUSl8OXa_qK$hKu0Cn%Zkk%X3`<%)lVsdtZ{{HCd@q(E z!gx)0C_GgxB+Y;8#OBRJ0a>FN>&HJ86Ub9Fvhy7hSBov(7Ycn55!H&Q(HdXFj4EZ> zY4h`I!Vy^(8`_)uCCyZeZZMHbvQMNEu5ILNA}$W3YmZ1wg9#Jgo}Hpj3?9NVCRJ}1 zZ_7+wzZoan9Ze9GS-Lj*(IUUgDQ)c!jbPV=-Dh^-3n+ps7G9Qw-M;IEIsZjsk>hBa zw%&32JtvILpSk~l2{DCT*jt^bt>5rfD6W@0_9oUdNIQ(6YI`=)^p+a{K0n~bn+Xh7 z5o@x0_e~X2a!QGM%rd{6UYAVt0o)S_tt0TOr+)W;3?%+DzM>lZrd8&iEB1wdRwRd3 zr*qC8Qh;2hrLQwBOR{T4psspRUv~S;PRZC&!_0Z?7>~VTdL$^WbojrQ7{SX(HaYT( z>R)1BecaM%4<9BxCFa?xKR&A~llb7jDigPo#qe{m(r*dkI`o;d{{=%mgUZnFO!L+j zN)SU3^-&e^xJ{}&{W2}C&iei@{~E8$OfksiAVelG=hZ5>+dS60N5z}|;5{Pb)R$qu zt9kEv@iR{IHbwXI=5rU>6LJ8ONnbTirX`nk4)V0%9(La{ekvflQm_l}ffn~(i9mkC z9v%Ve%P`$-xT5)=9M!q!yg_#Y3Q9V66}F56o*aDj&dh{n)r}CBeq`Cm@bB~4JFP8~ z{R%vErtOu?A4M5py&{HyX97`bPkq%XTUu3X7E7QK`}ImE0-IH{kxF=L1(`KKsjfNi zAb;7T-oaZ7XKEB>4}00plr(2;Qrd~rjs1jtyJ^$jsPA7gt|EAe0SiP^mS9WHR>aYL zCV#3{W4N|iX(@b81wh0ay#V+|=WV}hy7>XsSljq=sHd3#QJ!l)HK9Sv?(*B4Dn(}H zs@|#G$uO6eN$tCI*X>s(L)}3cw#Yrlu?QUatnFS{6x$A@7@1-s` zx*AR@LnX@z*|PKQ9T(tP58buZx7*~tVoxnnk@AI=-n+Ayn@GK;uJ*3)(-#}kKCY_8 zGgGSxgOd|#U9{uz?TPe9dC(>|a6 zXhcriYc?aJ#)Cip)m%1;nRo}D?oWTEytbIG?KP2|7(>;aua<@%EUbKp%-Fs4Omj=( ztieNOzsK~)*lh}R*6AqZ9k)V6)nm*86kKQnd}ue^1dRLCn=y>LOSRdh^N%DQ7XE>} zOzX}#Q?f7k;T6a*37B2=z}L8V@UTb~C{H4*(l+mb{RFi}pv`Zx$X*@svLq806%pBy zP1rBQ@?E5>BrI{@b}W^Bi`cHNX9hzjxL&?*9ju-%aHdp4eQBwY`E!VM7dnaKc`r>H zY^iTWBeqoE%LpCMwDLF(e$^FqMCD`kjyLZsGb*H^;a9ywl=!cgq;L-Iyr6w*Y{#MN z89Q(yq3>0_@tLJ#oCq8V+)rFTPd55jcNrMXeOokY2SQL@V%hB>ELB$$`f>XlC{_>@ z@wlXol{Ppc=XHUZN9XT#?3ip{CY0n%MW&jGE%emVxz#P_3;9x2)jC~)`3Cv-E$S_X zAMksw#var3!AtkHrN5f`?eC2HhbjBNS9oj|!ttelD+cD^GA!EcBYL-O^0dclC=Uss zHs1#hSzDnywWlSfuj4Q~!wI6-T*TwW;)U<+NNu{#!RWBLyaqN2nK7uI46|( z$K|_+-2FLg8NkVNC0tau^6m_MCB@lm;qv)2hcn1ZU-MmOV{3)#Lo%-vR z`M%kir1d@Tc@uXE2U)(3sf{%K!wth*BKcc2i)i6?xHsdyvu!gqg==n5#C-49j+4FT zhngCD@fGrern99=yXNO}VylN?21U17-Etbe&(?_Zwy$0VxDmDPw@I}uA-tcqp5*88 zR`%~AmhRBt#~&-^ms%e{UnjV2x*qSY>P0J3C>5hdG8vb? z-T6Y_S!!#bo?eR>HLy0{e|-Iy&kb*x5nfe1MboS2SrQvRcdzeZgR6zeZ&Z0=sW=m^ zD4%wmmKdJ&z;o46TQsEb&cdrM58y=(aE`*l9ZJ=cls@E8MJ4Oj)eg;p5kXHuc#l4| znxM0VN%Y&t>K-mDjHT~Hx8Q)KA^||hQFUdv_Ka7UeQT-5#>_{ z0_FtYXBDi|beg6o3@Yziew06Cx0yUG%iFdXnl9gu)W`Y(y>j_JmWl!W!I#TvDpTIa zA00mFf1tQ|T>4%K6~4h3g7tf&K*K*6(!qT$`@MEHt#QTvbqmd@?`x#YuMUDT24fwM zE1_c>bBfiLdis0?lDf9b&C7=U)rN)jP1Eb>8mUKZrMeSTU{_DS8)Y`Fr)l+i)M@@I zERR|m7H5r~n(C>vzbn?kx{6q_`ZLF+c{+yKg7wrY|0YJb`euta-Tb(}=YI^vdA-t@}|NkOWGx0AoeI$AJ3>6h!KekxjD zs>r%DFFfFt6FiLF=F#xlyIUQVsX($|Ta-54I-M7MIi((dR8cW^0t&M(E=Kd~Ie5Qf zZFc@s=qb_D#y&aX1_Oyg3`GKqGbNuIYAyE1cXRC4T9BP8(+( zeS<-{rhQ$`aa05eU;hpR$N@TKHF1+t9LO!yf8ZvKgM*kVVPnx8|3#LYsGeE zvMi+S=@fNNLZzFYNs|fJ6|Zr_ZiEkr6dEh<8<9lqBm{G|%2d2yITgXI@qARnTt7n=F=<^w9sNLClt{ne+* zI+e}u_UjTE?)Y|zQ9e-h6&eLPzR0+pC(R_xY4jjdvA`~vjiut}=j%qKiWrN) zz@%kuwNh-i$xc_1L~UCOYl4_@w3qNlb-G#(d|-ugNoUG<*LE)YwtK^r2E}xsQK&* z!beakGKrVP0BhC7DKa%kiTgA?EW;DP|SPIYU9FkiJaCP*;t(>o&mScf?&t0*rRV4CAC} ziTX^8-Q1{VyTBvZ1yzM({;1H%$mmg#^Mvc?;4A{qMHNaX;^``g1NW|@9VurSt$Nam z#szFNWh zy4>|xLRVxstZLO%DksiG4M%)r!`trcI`l{@5sL0bO#?G_QJ_A$V^jlV*-y4raC&CG z7}cm6AX~F4xSCE2#0CQ1IKhifI>}*y<@Z@Vmo|t%9G*3CQ&lXG+K`s)azjXqn|**= za^RPV(}OanIC_XUknj|UrIT#|%P3wUSCw}>{;?A{29YtuN1)V`$14{A+5{j)gJUUf z7qw)n%LcTblsHHRgm-7;0~ToNmnx;j8BZ06iU7>wbSCIN4#5(Nt-|B^R_R%-r~m*v zZIvt8EI`i*R0$w&3Jnyxra(IaBpXo52>?d*GE052qP&iiG-IkJ_+W$(kO_YOx!l%X zE-eJ0OgaG61n60cVMUNrdlDN<0I|CW5O$!o0gtFtQz-U&3C*1W9EgcSyO@DWJ)KsC z07%;l?rXY(7i{)TChz6q?2}|$fXOiU*fyXX0Se_^z{>>EAXjCe{RTQ^P=(=eC3*zA zR#4xTiX()V(rHpz1)L;0!zlyMJ2>q$z(W_b?!SU5=Prc;D0W`?;vGQn6b@|z!Zrx^ z9rSgb_;f0EW#CalpMX0E#4G`q_0&*DMf)2z3 zP)YrOpcjC1?v(iKb?G=2c7o6qoKyv9jB$#VUJ;y9<05nlhr9tbj1uAH3mYX>U^NI} zvI*R_0F0F$dhtvgGd3H??gASIaJ&n^5BCiztNt}3x`=1Heu3}-*8%Xd|9UE4aIbI> zpE1}!0F(r%8jced^FO#80KP83HUP`vXlNJs8;+5C>n}!lq4>pNg#U-rUEp=bfC&aT zIRC!jFJN~;H^aRd?#_j<^Iy%)zv3I9{k>4(fFoNsfLrb=lwAjS!h=223sJoN{d^b3+Jm+|*^%LGv4q_H?upLgZ!Vd(RcjbOIAbjaUJzbn8(-Y?$+%-smeAHas z=85_72MzzSq$1`Y=x*zH{b>1-$r30OqA9#M^8HFq;xwO^JUW@O?B@HhFWs+56ruOH zr`JRce$XzNo%)czE!2kcF@<&e_84sLqfjVadyclnxXG=_q#v09%)uTZfgA;s>n4Lo zxf@S-e>(PE7F^;J?i-Y&XFX%~lx>3%&E7At*na*GBtD+|9|&G_ot^2RN06nPXcP18 zTU!(ps=J}|L)#|?68w8vLR$R4MyF#++AJswI3$aHoz-@KDZT@Eg7Iq}_4P@BxDsEI z6dsKb#d|26mAA(0Eali3Oe$79!H&1WFlp@AYQkC@;B+TzhXa|KLB+Xbh!rno6|x*6 z$QyQc^)x|ZsnAkq86 z%8NUn9ehts+0URZkR-Fork#QlG(nvNOVWC`*a@JixY#)6GESLDE!&=^dHK7y&%$e~ z(D^f8tG?FduZcD0}S0V(z89I8;d@#EsWbK@qu{ZcNw`nTtk zsEGDQcI>>ROFGe0s=%BCxvR$#S{ki=e8eQe8F|P@yXdii^^M4@O*e*0k5r-a$34NUvtSK`zKg(~L7j|guYHcXGdeavX%=289(p<^4xb%W?)e#kK}u3x zoMH4GVaWrrlH~3tq^;qe0L#Ekn1gB5A{lQ` z_q?-a17~DftAMGMK1)POsD|c>y6WwayPVn-t!=S>Ko(3n5-C~v`6E|yVr4B>c+|`5 z^7F|Q1CFa$j=>>!LCe`h!wu;|!_nZhk5Nct>ZN)TNyDM|aVY1#c_Q|-b%V)L@=Mt-GVs5HLMpm><>>tu z6Sip)<$ttj>8{??v_CM_dl#**C%ZW>q^K=TCU&og%6V2SGZ%HgjMZx1Ei82Zv^^tt zk9HWi4(L$hh8qi~BSS}q@N7-&;;Xs(h-(slxti{6tOMloZH73E4WJq;Erwr5`w<%J zD|FaIhVv_8PFmoR{Z=-u9_9ey?|| z5A8Z<%h~2j_#UpL_fgGzejQQFVegGEvb5j7sQX|LWB22xax&nfF2GfOF%o`h8ky{M zxr@wIc6R7mrn*+4A>%~0SNxiu^nkNuXo5cdU_tNc_Ty?8ov}+XV>x=m z4$MQP4T(nPuQo{=X?zUQ-`MAUL)kqp6nDi6w;n~W(V>o>Ue$*h)%et1qE+Wc)HZl81j?U%x8k*%~9At%QGMvLy)I zZ1^eA&%AH4&m2KN6=)IlnzKa4O*Oy9`~5-(W2k|_ z9EE`bJR#cjRfei=?vU)lZ8}G+py{P-?+SR+ z19b30+i8%*$Y6D@$=m+o{6Ds`mHC6p&z4?#LtPN}Xd+#dl z7SMc5G9DlHm3FlvnBp2#rM;f=^0mGKR2u5WEDgb^31?+1R7{ca`#)W92lmMHM8SsM z%?JI*`sRo?W(uO%J+H&rFh~1zV;I)4-dm0SvK~J2r8iZ(x=@VFvDt#N{=!Iy(n-kr z4r6BQTy!KU$m4Qj{VeK9e{@(($EI)esO!+R*WEz>3oM?*#o9wDYO~WdoJP|p)%1ON z>fD)M=GZE)=3#tYrT*6bwXlbS%f1^#)L-xXIw*8^oB~E+(EAaZ4Kme}w(rh^owE#X zGE4)EuVdWW8oLS%*yT4}X}8XTtWS7>ces##c;i2i`^wE2^YcskFH3B;1uXt#75(`+ zG4E=@dIq(((?39WCS31dday_=MigOT^qKy2eyO7;T;f0$UEtMZI{m$w{n+sJ`K-2P zfzFY(uI}(cl2L|VG>3A)B0iGjb7uBnqA?sb(>!aK)@I^!cd<^rx%KF57#&la2|KFO za~L#mKG|RGfC2;ekkY)?dB=CxXI}SeAA=unwA8pN;o)Ppf(L-uQeJAeb-&^D*u+hw1CT2EfJHxqX>#LM%8!L^liZ(9w8pF?^a<-Gw zB0xJfdsB{L6Y?iMG$iUgq&Yo$Lu0bn>nbnoG!j17(>}sPn~*-}Y=Cy+PF;QyQnGuP z`O6jC|7TR)(|FElh$l&J<}{a4te;wZ)s(%2c0A1cT_!>;VvAe(5gO+^#LbqAMnLMU z4l(d?;i01-_#80H;RqHu^>7#y21M_U0q2*}bOK=ycLs~j@3N^p-=OL z_G-dEUN>!e=L_nBI;KqXKm(>kKGwmRN~ovZbt95EqhAt*rHaU1b$t14WV_@xQdx#x8i9Yi_>L~du+c|@QX80qdfL=hlw2Fx-G=1Htm|2d3?L13OuKiwf7*z%6fGgtwDy^8 z#mMzb9MxMhBrLH)ld9}aQ(Pwg77@vB4wcuB3=~-2t0DPK%X(2ij>(zKiu0&nNJMj( z{Zt}W%!Mv}TWXs62T~mRW|v3iPqFIc5-J7tAdmjG*nIdtA*L%4t7o2&CkKD1R{<+| zpi#WKC*Q=X=ivYQv{9RP-%6tN+KkaPAo zw#^PRPok~Aag$)*d)fp$)lVWoeX^h239?)l45LjNsH}QlAY9}B>-Q;2YNq;|q{t`R z{NBy&>MdYCjv}~lq1n{Zf`5ftELSP9kL*%}e4Z9u94raSbyr*p9K1)roP#YG)mOar9^ys1Xsn98R-a~#~EGuN7jyCQ~i%m1QYFau42S zK*_tDH&ho&K=cZ}1VUL{H$Jp!FjQYWJT0uQ;6Hv?a*>(kffp3^u==>)Uf=Ikpk{ve zd#{5WR2yAqjSfvYe%Ia-&?|iKMz@2yJRB>XGMof^1;KngmBm{3iRHbqita=^D7GlV z-Nr8^e1Ej?BrvVCty(wUq;G!vHKB#d7iB4pke60malncFDS9ZNuz?Qh5)R!eAw6?` zLNi!a-eDr&{0_$MhSx}I--ulkAJBO=Gczv#=#S|(P4jD>G}!)NhOi!mUM{`{+vl_A zf3ZMHV~ruJs*JN&*+au5v?Ll?Tw!l9sV4p=0kQt@rTD2*yd}5>31+hf^HUc`mOQZE zW$-ld?>lWVT91rtkVNm^IMqN@$4ne5Z@@+_S$Py3j}E3An+c9TFYBloED%#KS-Zz} z+2~iPMd`f*nk5A8Ow*!YkN%23{3ya2wFHIURo6&fcmvcXs@TZ(xA+1rP ztnISA;sgBCt+R*qJ~2CgSY~>v+D4w|xrnhN@Z1RMY#oPg+HR(-AgtT-v!n{E{0OSj-+gGmPh{AQSN_*TE*p;gW3B z;63Hm&-gH&XrQ`PFFd^qA|RTO)BESjO4^XewuNM*5BQq5Sy=+0Y>q=K0BtL4wXBCc zR_y91KTo;v%-**R@}T)5Z8K&05)ysxNk?p76n<;m zdt27LNL7NrjM^k$_tTsGmPc9>-42zJHG1!zX}J|HSD7446Z;lezO^UlScOE0nI4F%CkF2q{uF;?dI3O#aNm@qjBK{ zvTnp*9NZkT-eS>srODZ9kt8DO{(Pe>Z_}ar*up?#d%aQY;mT?|E0c3 zgsEdXwIu(rz%wA51c}O!q~za2ta*eG%s)*rUQ&@+O_Qrzy?kWQI4wT6(D+p)jxoS3 zSl!fA@JSWlw57loDBWx~G>=WRgUV<5(5iR$UOY{*BNR~^WKP>Si$yS+#*Sjvrs@GT6K)zfQgmOu*k7vfPY)KCt3H`$dI zlj@UC96E>p&4O`yBds=O_1i(ui-jmi1qUe<+73}y)upHj749-CMkPtbIyBCRhOtK0 zRmZJZG9(_$Y*j_8MJpfDmp4~XB23PX5rb=t7ql-(w^=0qVrBANvIbT#Zh_DJI@Z$a z*-3+D@NwjD0A$uKiFH+)z~a(g&aa5SSgNv3nyT3rM^WR6b{d8v&LIe_#mG^3$9%gu zG)((-zhlK>9~r2a0g5nV`4(lt9i<)};rgsN($Zf=eH21isdYx+AoV!te8FB&wN{lK zdUWIt{a-A%%MDq*LMk{Bp}vH>(|ts~^IiTs9kcug zTPLH~ndYO>9S@fymA_LtP?F`Ew|tX}C%&ff$HufFMdD$9_nlj4qy^O@dfexnKa%zLPr$;?9NXqg^*(Rr=@l(&(%tcW) zJ0&V8UqVv-0%EShzyN?1`E1b zt+(8`TZcVnguw5g?G^Ar_B_Dwl1%ylp*?2HP$YYgDH}}p@X2_qc(GP*7^}Xy01y8R zAApV3-Tc%&+ZA_?^o=> zH`Hu_8`ZhyJ&Bq?mz1`zV*cLo_DlZmi|U-E{_B2~(T>@`21^v|2HbTEnHE<6!v4EN?)EN5M(QkIeK!31NelrPk<)bfHy z2q`Uof*J$gqd8AzeL3X3%q=Y9s_YgaQs<0=X~#>8YcVm$D)5SWkwKt(NHRT*dQZne zi5j{^mesCt>j;@3D1pb?C(1v|1w*Ulj-hgaW58x=2ZnDjYQ=Dng8u{Fd$0MmOB!_hJyKWqJw6%q znOn$-Gd~~3I5S_*fX%?TR5A1|km|)uj=`iD5FWt~J5j?G0Bbs0u>%v(1w;0$kuuZ$ z>WmN!k8M|yI1!AjLALq&fD~rN45pjF?FuH+!A8G=}GNwIzeQ7@H^{$^CP#f`B)eVO|Z$%`xszi>wvQ zUV;Pg{~3>I%@BU*Sf-yAa3owty{C><41xdCmtLxQ>8ndZa zLv?Uyz}Ot~Qp}|2>g88yXv_iBVajg7;*W~}(9q`H%!hH$1j2A$C_txMD)Wx0nag9q z%Q3x$NmnYsf9K&KXN{?D1k|d3N$u;H--O{wG4EE6&L|J|-;Cm4nNc3V7+Zk|_^XRy zZa##d^E*OmyKi1M@pS3z-F}e}Y&0!BpMqTn)&|;$+%e;BmB~Q#4{hC*nGmj{7q zs(Ovt68}G&jj_mLT)+Q&xQ{st|4jU#lLhl%VBCLo%Kv*TFoyu6v|R0Y4A>oIc}$_o z)$1_(1`Z+ShpvwEw53AGoL3s0Kk7r+tPfE{iG5wZtmO6k@8|eOG8w>d-^miRTc#U> zk4KEE@%$g(3L_Fwfoq-T*Lq;}pk~K{^w@9nVN2OBm>lL{*5%b{o$u_Iv7grgB-X18 zIy1mR0$~$yBKhb9xThLUzDCv(D&tB#Cz_s7becz*S(4$I6|fDes9tXtAb5Z+)ymRx zl<(^Ofid25iOOYN`@lS^Ux0W46KwA<8Kx_Z5w?YFJF)7y=V;h~B;mnyPIbt@%l=0> zsO;j3nX(_1g%njwL3j89e68foh#{JvF-viyZ0lV@+7|9lU#IEv&QJp7!*&Cbe;{ zqoLIwzV_p_!H|PWNDe;X=<|c1_{>fIJLZpTr9H4{d~TrNWQX<4#E1jr+0XE0Jt4|B zy!K&2hdFlk8d=!0)rEX5?eZeIoc>EWzXhDN^iX2!@)UA8Q@7HW&zm;&KYwQ(r8g4YA?>NMQkU0!^vBvbJkNj8A(2+ z+0rDmcPeDXB6v-?{hU_#Zct9 z=?oF16SADD1b41!nHkp9ga$b>A!pEql|z1E7UBChxFNrS<=)6$P8!h@Q!rhZK_9va zKW2R^&>!BH^t;IxF2ZiL(V=f_$|5bLaIRLd{Uivndah%i0UpZuQt;*7T#nrcc#|bK zY20$D)JUA%BDpk#ZSN{qA{|OQ{Z`Oyt0`f>vUc%fM-Fxrt?l-H(YC6lHtMWo#4Z>O z?Dp7?pZNV*dnoTt-PpK70vXM=P%Y!?{puN70q4NEEaS_~`dl6%FDxqeiK?R>=h3;M zC1X&AeZ8IEx=`C*9;)tn)DLy_057^F7+=od!$A9>`-U<>qltmVo%}(RseVZV>157mq~@_= zIFXc!#Y8+6=XnCaBZV3TyF|;f+C@&F0a#FNraic%c79a7ifYmQ@$y}Q!SXt}6225A zqLRrr5it94@f>3&hClEwYQo%}M=K1o(<2G3?hO`aMev}>an97(@u^c@TU*1R@Nwq- zUo~7RQZOZ}b$*MRV6av39lULYa1OqG8&v19spLWy^lrdn`4MtZ#?dg|pf9Cm9tz?o zjHus7Bu#1cI-X&fuB@`8lVq(@x4G?T65m*}MIRR=AHP9HGgQ9W^FKx`Dph>aZmYRQ z%L0JzQcc^wu&)k|)zWwsWwr}<$DeA&!haPPkwbdFO=t84ZV|qf58P4_gMU=M{uhe@ z9ov&M)G$KdpkJCr?U`W<=`9OmnINno2YDzJrurPem9%91knpCYb#FO&%kb)&uDOYZ z*xvQWeEl;UIATIS5TBc0B|{{q?+LX*lqDe{Dkran(7R{Dm1%sxo*jp=Ft#qLNHE4S z!6ZO~WK0>W#adBeZRgSsfs@F&=EJ{OUe22G)-Y@5TzJXMU0Yn!*hRJT=2g1YdNc7z zR)G%o!b^_m3(I2vd$QHU_d`b}Ebqq;eLi3M{iF}qYjw7IslQl!uQ|MLr#J0F-A=+G z$<#o7uSD>u0B~R;{$YB%>a+ifAHUcHR!Vn9>>s zNPYB0%rH`zu5w4ThfUh3kMigCMnz`&oU|Posbo7ADk6L-r@X@Y#Qb}r?*J+5@k5D= z%0Ug2xJW@Krt7gC)39veC)IhLcPJ=aKb4{nW1*{c?;i;P6wbg1-(BO+e+F2%D^>5? zK#m6+4+e(H2==x_BZHyLa!vDtXy< z$oHVcJeTfm!{)a$S(!ChUCbT)jzSHMsOcKppl%xn!!E |axYlWI}23_9KtB}r>z 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�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

suk8h= zKTX)>e89HVY_2xfr6xQejSrzbuoY;@34NmQU|st`vVWkY)?m z^2>tTw@`}@Ze8+-6p^OYmL^HL%N(JKN}o|2^d-5-gPzHEMd*`Ib4ultb3-K2xtYeu zlwkA^V?Lbx9%KwP*Ks87v@-Su^KX74Inn+B0*P{FBUC8Qg;JAX|w-Fbyx@G!A=!t2geti)kHK_<_<@*+RuXSn$rDoY+T0kn|8CItuRb zBz&MUk83Nf%cPwBHN0txhlg>xm>QYWMzjM4#y?{GYP*RHbRn}iqaRjRY&Opw>eq+} ztIPk*yZ{`&Y9N^U=(>?!Li{FMgsK9~nD-_jXEq50lzS*#y$Zh1UC#P_PU#1%KTE9< zKmvyEM_WczMEj3HxX+#VK#l|U=F*ar|3L<^@JoC<<^Sr-1+{>(?Z>7mWa6N-qzuQt30BlgVXLX&!BG(=9P0^q2|@OEvP^B`FHu7ytx> zf}VFA&SQ~ygaYBsL8lFFu5BRg+yzSsr83xEZoctFR& zzz+>GZEm_iZ)&LiE6EJFi4;O;WsS?;k*we zG>L%a9RM12I~%;?zq{0FWzyojAS`_-kBU_Q7Qx+lxSJphARYawJ&BSNS_(tSh;YsU zrh8B%pLr1)&vdQ;0s^jkvA}Ong~#i~0o9tJfOtd`xZvmE16<02JiUs&be>p(ATo`%>XsC-guT$>kp7ap6 za}RXud&eyBOx%q3n6~^Rg8M!Ub5${{)%{(b%uYCkNwaU0Nq(9*tKTBxDv80mMxXwJ z9G%ObhXIk=TTmy?0cx$Ee#j}!{orIOe)LXI6kod|4>sU?e9Bj{eiluMv7OhbCH?f7 zkLz;#kZuxFXN8I#GY-*RF^XfR7(#12w%=o;nbh=n#yEeU1>#$5HtU5vqIwGcgTZjI z!@8dc#Rw~MocJ0mVZvGdX%Tn{;KiT@lot%wROdS=-(l++3#Y1tq)l$pssU`zFShL^ z&-x>DJ;z0%Yik}wzbn+j0R0*svP3cTO(54Zff=DRRrETDsAR(Sm+kC=v8@A|GkZ>{A#v%9fCOPVr)7)TeJi0<=>z00 zs5&zBXEmNkiFOEzo{1YCw*lG9*lEjFD|4&+%}@t453|* z%q%!?PXMw)qtjmcvM1&K3CJ1w!la-j&f$6c&d|(&Q+CLO=exFweSfz5DZ~VWsr1{^ zUo6Emc|1EE#2+FA+-Ob)udX|^t_p1xdA451*hKmKw8pp+m^ybRWecIp)pM`j2P9O^ zJxbo#IIT(>w3&}oofK=KLcY1(Qe;ln>lyKaC+jkQ=aZ|f{l|kev~ceiLvQw!Z`ipx zYp?$?7LO1%4;}P(>#6gs=hUyEZ#m%x;cmL`yB$@^!pviLu>0fDd~Zx5ppLg{z8i%p z^NPU6W~&{Uk2V;YBu+kHEC=^TUA_{#d%sx()wZp4alX9zM^-)Gr$KDosYi*SWe1y~ zG0-&6R+qq9AJPpcXOLx+;R}6ng=5+k7gmFCnM!(W&2kWj;!**5#Alh({KW?W_ z_KRgpdd6tiEH~a#Kl@n85?LqJmj8+H$(D0C48@$kG1SLt=w3Z#I4pOAWkQ8bivjlnNZya+`3AFjU4bzA*2MLd+IrNp7`U*zTx{bFsH3!gZ%&dUnNx zU&yX95vpQcUDaYaAo1MUGvH3&OWg0F&J1pjB}SJvWSSdBW5N8;cNk-Cp?2V|dG|iN znTA#Ronz0w_+&nqfWPxtoh*g<3coS{p(F3!h4H{4SruhY_Z+L0+OGKA+0n9YmVdrq ztb`}!{IKoG2ul-~C$s5?qTe4?L?=A#U;$6*I{_I*?~&*+;MkJt+5IZ_#x&8?ncrC8 z6HAE5ql`B!JHn>N&Y1^sAI2Nj8c$c#Vx&v$%>SP1DLC`b`u_;es-Kyz;6p(QgKeJo zC=J!!(y7<1`XKqrZYvfkYr;9J9N|@3>T*Z8g&qGPZ(mh;=7&63FiySDSujP2>rEVn zy{w&LciUmBktB!}&YTKVA0x%-tt^M1m)n(%Y>AUxu)c!Q8@kg*`}5cuJO8G*v5~F4 zWWShN)y|$^+#~a9J{vqnyuZKKKA33U!WDC8*9h?xb>+WO-5YC2gjI{o7pLpZ-|;dz)U!zoF(p zqr85CoXA`J8~;#K*_SxpJ4EGMwBz4V-M_p)ylkRBInvsXYg@KT&j{x16&sil5}3m8 zIGQYEv2%DXp+d?|m7_MsBN~1e_?$Y5VAby`Pdx5_oAU=B78}{nxN5mLdCChjYugqE zuCwoe<-L67X#JClw$nu~YSED$ltXi+G}PUQYEKpWL|4O52C*+<75x2l;-2Vp^_IH( znSJ!wWS=(~rHXi`y=GXN*=@E#gx`?Ra0T#oSHA1xfA*lMDsS}-G2tU(_CjS%EL#aW zh1uCmG55%zvWD+-Vq)p|^p8?dFi>i}6h&I&?_Zi}Az?Kk1WOPf>ZaD3se8F&qtZI^ zexCsCp{KnWaZhNnU8uqBj63+9)#YDEW`DR%I2WUhi7{(Uzs?kNjNu}u04G@T=_m_; z@*~Kv;FGSSzNmvl9IId#G~vysrE-~g&tK{Og}SRKlWpk$@eilm6Lx8TDkm3X>&P|J zm^QpcnuNZUgR**J<(G~{|7`8DruxR{P?JSQjtwaOdQTXNUZ$nJC4Hdc6RqTKz?T0c zUtw9)!$hdnyWYL32XHMApdl27Qg9M(TpcYE+| z*z~L08mj+69#69$87m*8p)Dq4OH$m}Gg3bur2oQWVKh7y|DR@|_p z4hdpuEfyI3Deima7T-~f8XD{H+OvK#?+gMgJsVfY9W%DMkmd3&M}IPgN07X0WgR*t zf+L?Q8QN5JtPUJyEPBy(HMIPF&EpDp36;bSZD|XAa~2aiT%>} zxhA{oN?MmREKmdGy;!W%luaVt4>pddvR%`XM}0EcP7}FoLY**S#Q||fWqS91of@2p z<4cqA@Xcr;tNcvL&*=P3fyK(SnKUDg$1kZKEKL|bWc$1toqlFaFtJAI5F^$-p-+Kl>F7XXrSz1x4C+CI~pd!TSp37?^h~U z_RkxP3`<@Sj}2eaY}u^<4uB49y0W2q0EoZ2^%L|k!L986I)lhPeTY3|?l6VTY}s>z zx9`v7YujChzxQHUy!V~Urmre7)=csjv9-6{{khlTv0sF%Q(+bjtsQ;ceYRb-w||f& z9Z?oO3Vnk(dZs!3%r6m^9cKL+p2pbcOaNpMKRYqXlzhJIWPHoHZ4aBRJt*Jjkl0t> z6+;NTezZmOoX68|x@ltq%rus3)o=FELhXyH>(}jbL)c51mekODHxN`ebNWk+qkDyU z?0;kh(vg`6Kv#+-M4)N~3S6pJhSxN6%rISejtsBQH2W#O+XIvv0)I;T?^x}|K`Jh}45GWT#mRlU}B>^qMOeC~e3iBU14c!IM7{Z!59)yp3d z$00>&f_plQyN{g5zg<%6KU8Iy+)@eE=-l0*tQg9wET5F-wuzk;dp(LK>k#~Gu_R00 z<2+lkUc|JyBWd)#?q}R|A{kWfLR#~<>4c@r&Rrkz@U&D^>WajxX#rqkKV&~Pf!lm( zv2kc^sGYisxDP`x%oK{O=~wg%afa}5rzKQ#sVc2)sXN?~%Iz;UswgiSTAw4OfVCQ# z7#s7pH@pV%LvShFDFvWs$)-DqcJgT5)O%G;7Lu1r_w z(!U9+dElmf$$Y1WZvJC(y_JQDO)lJRC5-6*lOr|XGdh32g>OrPki^~Bw81uIwHsy` zY~lfAeAA7Vg;oz8c}$sngoz^u`+COD>mz3#K1rraB_(S6JSPr{7v1qz&0z5lh&SG> z%u%m@b9mt6JoWr{U_uXBATr?v`qg=_>2vBPS!H&=_Hd9M_}W9&Go`yKSeyQB_Yj*% z{!ja}!8YCG{B<(?Li#O0jYp(Pg(;u3?z4KgJx6Og-3jUDF-`c^=6L7!r05f~ zsU&{dF8-TMP6OX(E>V67WlNJG(_$!lk$STd>U2{xCH_r{kG||2)qCgmRF=7Nu60o= z%1clK2^85@)my)d3G`4ie730 zr&q^}XVPNGs^0og6&nKfTlv|l*_)N!b*GjEeTiqcO(cKF<(a$~>B)*;EE*YANATYJ z`&B{ET~*ebj&vYb+0$_*IW<%0TH9tUjnx4hIm1MD#eJ?p^4jFUO>KS;Aba_pS1aZ2S_Zf#P6_=4idFP3kCTcbZaV)C8J*Y%db zTGTUG6SC_6)h|%)iGi8JQV>sRkYQ zyFI>mL05~5$F*U1NT~Ut+J&sNZ)XcHVd|plWk_0~nW4|rSxI3K=p}BDf>`N2lx>al zs_7MukN;ctf$ox%)FmSCW4*FoVN+A{MGFI-g=7=wRVN511)ZKkFhdT?6;LS?`m^CE ztGeJ!a@3QbqNnSPZi7Cs?u20{2|CDU43$xSi_71B@5D^V`Ifj#5*UUwgtePEA@UNV z>8JX&DM=1kUTK~{QllWDDT5g8n1qp%oUWEs&m8?fctD>tW_`Y_uD!IS4>8Rn;n{As ztSEwpT}yE4P@svScPlTgLgd^q)iXa-Z<*7HRXhaobgBxJ!a5Ic_v5_Rwl;7Do&Bh^;W5PWN=(|SBB5$uM3!dD3#~5I2OuYr% z=?)nj>5k+FEl|h=pk&yZ9$!Rb?i6uCWI$RPiib*HWz~YoNh8>sb>Pw`XeQoGJ5n*_ zU_;7+Wmn-!O`O{?I4cw02?K`wMC(0tmTYNnfJG50b#wd!s~IyJy1+Oe^i^Ox1E5G7 zyT$@4Swr~LF#ZQ5D{$QWZ&vix5kRAzmbJ%q%7_QpX8%tmp}RN{ns85r>D~!$z!NZC z@q5OvHrAyw$pYptS8n#(Hv)Y~hBrpW`{HQGTE>>4U-?~ImqTjE?RdS1z!RoNE%AfcxZ*h zfVETn3@~g7(Iv=o`WV|VvT8w;-l_t6i&BdlOrX4Y7K02n9Sw->n8nR!g(_N7428~_ zNx@)kIXlpMX*ktB~E-AWlnM;K@M3| zG)Q0LRzz*T{65(YbQGIU{)a0BGmwgzcMXdW&eSDeyt1Vo`yisyi;T$-AKSI7Haf?G zzeZmNSDzSwe9r7c`PoRY65|6S!?^DSvH;}j1N5dql!H_zWHypVH)2`>BOZ8rtsJ0Z zoSeX!rH2yT0r4~dH?leL6o5QQMhGtvK8xwUDB{~#LPdsMkOpmW44@GYggeGccASkx zVt;0@pY$j8^bos9d8HGa%52e9?8q5C-SajOU9!A3G%3K1H1L1$U#w>Laux$w)nn9E zw*kHcpkLr^3^uBF&`?x{upnuQxa`qrApK&@A<=G<5VIYoPO!w)nMGfF<%Fx~ci8(% z%fsh4vRwXX@$&}*pkQLqM>zq3TlT`Uj$ite8W$L$=jY`Y@N{l*lP_xK+-9pwqR>Pa zPx4|!aJCb7n4=+HIoTx6!^Fj36v=~aO7Rf4KPN!1b3C<@0Y*H>w>2s1;G4Ogly&NZ z{sz=}@++K2FYKF3z#djp*r{r%9C8_z~_abL^_pLaHtc|nRO=VtwoDu}d*bdHL2x0FE-NOum3ii~v1(48}g!~jF6ba$6@cQed*AHKhP*Zsq_ zT(TJFob${x=e+mcuMGp4QEe^IcnE3cVvQ`p>Bd5IFiaVq{u7pbpfGZRlL&^ZH!TN4 z#@o2^KxIuX@ytLL*3SfP%f|~BCSaiXkz2vtl12GTXdg-bl_G7e3th;H{m{ptOGg$v zI3eW#R7r#stcf879;rPQB}Fiz2D?Vg)%|l=t{7kUkECv>V z`N|n&2Z^`1GXrx9dLJ#(er*I5idfi-R3JFjZ{2q(hctrj(MwI4_ycfZk_f>l6~k>-oZ(vaZ(^4Cl>XLvYAl}83mcJA(jx&;aI+G z$7B~@1CF%$1lCB(p=>(vp}Pl$laLrWF-}{sg>wScTnmhv!S)7nZ`3t1aYhHHwynDn zIR-W0%-DyErsWvH>vT6?dFQPeFkTG(vSjB2Li?rB@BjTnmy-bu$#ODrNe1O1@eHRk z8a25w^b(GD(oSQ4H5~S_bW}CWqdS{7)5d>1t=XTV!fE&{*p3UZ2TOul`)Oa6u>^8V zF&U^R>2`{5@?OK@hNm~)N2IH7bl{W!4n#EFJk^jQ&^tk&oDV8Yr)%F^oiK{;e;~Kw z!ZK33K?d%KYwdpY3vamp{L(&rv2>=x#Qk*_owdB9kKu0R;1BAZ)7T825OnJn-$6(7 z71PyRnz~fbHr?6ZL2hfgmFqrpFk<^X>cL=fZ%09k1zR3n>uHQ`u$I>V<)k^sj+1w8 z`K{_taWh`lgy+%lT1uz4h>Z);!U^U7f=nzn* z@tWQ+!c08MJP&IsohWO4_&Ksf-5a=r`WG-E?A6~+8q=YTve+vw$oMe#TvjP8h2t+C z)37Yk{w-63CHvsix+0EdWLSBn*$7wEcp8Tz2V!(U5T8K0-JhSq@1=U6Ncd|M#gj2A zBxd#xqBt0p;)-hE!PAv%G_!6orp8EQ$g@rm4nZ z$qP(naPbr)&cMO`c)Y8qC|lhNoA3c#K4oamrOK)J7e9vA6f6i<)mLu!&P+BIZb=u?!vp?;A!C zJ8lhUWFP@W)w&ab@%5XPqDgc&)$<8B-XuZ|y`_Z4(a--e@AKDw$Tqvx zGqLq*oP2iWG8O$2=$rk<0ZO4Okd-~`{z@o+ctzfS1@cJHu>Z77l^|Rdv7S^&O+Tr4 z{6jfPa5E;lHm%0j;7-bHV?>D&_Uj?hJc_AdskkAO($MGRD{smBhnUJ4!U#fst1w)vj>x?>ANL^RSv$77c-Fy12PR zE6{>dI#XF|^1=pPScK*2y|{KG7A=~=FyjsHDvEH)ioMOe$Ozi-8V!Kz=Fp+CRihnfnYOmMb}^3fF=x58CFM9I7RVR)H1JPse+2Q+DwduYO7&CYR?4ExtC9)v*PdTE zzxK`lVXuA^S61VBACy>zDW2ynpl2&*dK zGV93H7~C2USw^bvD)gjjnc~0PQ9q|%dT|;_=oFLIfKEz$^O?dN79Lsavf<3|{v5&v zq{$&6Rty_hcszN5`9FwTf!DR84HU_?`r!3ExqAlf z*)Gl-yAECl6X) z!6%WDY4j^wv>LI0gQU0l(oSmtPfuscte_S4RjnRlDXX{kmliR1aE}v?14h*>tYMr; zF4VhyCE1CqdF zo*d*7yf19yWJE3Bc8tCC2`~TND<3F7LUh|;DnDTHboz7ea}%=gb;v6e~a9{K4SG z;&q&Zsjd1P^l%^?{srKG6+snR%g%%+OALKs@N!{-<~Qqf8v~urJ3AC5QK8A0jaNQ1 zMV^$$ZQGC8@DrGhMJm^^k-XrKUok&<{IW`*GcxtVy{9R}cI*aWrT2gR^*qd^Z~j!0 zp}b63UwSb$rNO--<_Uld)+|PWG1@Q5pPUbPUNx`lpW^#iguUISb+E8RK}P5`d7b@x z2hFm)EIS&rW{Qqy*i^>-z?QWr=)Zwmp_wn<*H&q4x6Ll7L$4`MwH03VkfEnOHea%* zP+}@;k+zGZ8$I=|g!NYJc0EyGI@r=Yr%gedodz!t%UHdMe?t8n_)v9o@=I53ASa1^-F5wt=&uiAbP?%1~3|is@SFB2j!`X zMlF3mMMTRjRea|oPL<5%CK*N6dUtnNItuNOrcM0Pe~KS5#{a3BJ|ns)N~4zTyY+ta z%Iu_*64lYxpR)-fv(D~(T&?q_`MQw8H z1fT}jkUldeSE9ai{k33|# z)A}qTh_@0OL_OUA)G%*UPLs#_lmYgj5>B6 zbS=z&L2G!U^O^^E6znPt5?ouQ4P@dvAcmDCB@24xa(vuxS9Ue_s5JtH@}d6W zN~^9TuW-+R_1sjX!u_F`*}#_>U3U_^QR-3W1gYJ}`f*Uv>9v19!S-VChuHBiLaeNE zzV-;`vO`|9wYTZmw)B~>tIAMbW!!C!x9K0Bt&aU}wv_yGv0*1S@Or_%v7&cAyxfr44?`LDTKHixS` znIqd$(_(Cu&a5l}Y&vT@CQ(H`ayQhME0Y3f`sq2-y!Q!SC-%KQYZb(gb}vT12;rAX z-+jVmSK7t(Z(3E=gbnL*(>&nCDNv9KhS!d2 z>O9}rQc-v^+|*P*Y+2)6F-^}gsx{|uV))_>Z}ILKB42{*Ws%O~*BP)YuC8k1eRnOO~Q_42RxfQ>1ccOK(K4_0DuV z*q#PIWAozO`{T875_~#(?~&i&OQDE-k+U$=4Z_TX^K$0agf|Vy+osoxob)Si-4GeF zI$LO;f1<#FKcCB(>aEa=7^wLbUb*jAL@3nh#k+nR(jwcTGO&L5)iYBRU|l`+J$8*I zpLO00HRpKuI+{w&*?Dd|2A|7<<|!G{Av|PtNUJ7eyEk1$Z`^%-`eja`UB*3`PQlyb z?W#eCxiFtj75;P6rmRXM*N7Us#JKQ-1MAeo(rSI6Ms{i{So>RBy4qU8{6=nQobPMU z#6%2Kjm4g27$h&qB#&Ctx==EkH4}8BoJ@OPn&UUkkqaMqWOkh3ankc5(Gn<;KQjZv zkB1w)%Q5G>#B)Ezq_he)_-$VN>3C@7!`h(mE}YvqvGh-+5 zRnIFVU97?PNsVcVI>A@b=b8z;K`SfQWLDb=v3OZomq?7n}kU zHO8NR_^)U9jeCi;PIt5OgkhWh`jvGYPB@#Yf6i>`C$DBo`QTidbv3~7+RiLuIr#!m z?9okSMyIyxdUGEVzeoVZnB%;U@PPkQSUw3&}+4CV# zj`!&-*UB1VzQw?5`)CGs=VrGxITkA@NP&%)dT`{pWTKlvzgTSd^`bWhKd9jqR-`!I zFOWzy+P^|O2>-rb!sa3 zXMi}cU94bIUq04ZuGdo>Q;-`q~Uu~pr>L#9HKYW;~wm8-sq@(&f^;19kHRk)1}y1WG^um z!xt)}9Mc{c)yYpA|HCU_Tl2^Bw-#-G&hE-oblLi3nRf1HvKEN_fq1u?=!)DKFfx7E zR{d_Q?HQg@WRqM+$GCsukwIByEa%;^ug+Cv%!H5CHHXI6TQba|mA@L^2;Jn!T)7gn zV{-Kmx6IhE{D1d)94dvsMn3hl~E( zG8LXmmX-Yj_QiCpai<02BdW)X4#fld$HR$ds^iCXVf>~eKy|J zt8}_08h*r>hk{tDhTL(M!ULsL*C74(DCTV!1Zuw^ask~xl6e1(5Z-6hHRm^l4@5G! zogoHGR`@qnL0RLuNoMLj3>cZzSKaksd?tW#rVX1D`?%!5A$4f;RA%q6@Vuw!_Az3( zA>^d~7xZi7bGkRGBRPmwhQ!y3cotu`_BHHT-yw5xMiERKwi#B@W$E+1BW!A~ccAP8 zqd^W|MI7jf<(_ETsD4g)1MZf#@!Dy<5N8k$JvP@+*VgM>edilI_HB}57ggXV7L|ME zh?+Ya*Of8IqDi%Ll`Su?9K1dMYJMtza#0{M;8 zK315|@Lr^svjdBT&*zL4!0bE88z`7vi-CoQJZ_yzs#lLgrEmNsZ$j+PA%66nnf9vw zbwAlL#`KS`d;BrfduU?u--T1L&xb*T&r^#{@42Yq6Snu~+Kso=IOUeUe>mHd&7ZBr zO0y|`Vc^_G1nevJ9MqccP&qv>@F7Cf-yUKTEmp!jbQNP_pl#Xh$)PV2#xg&{PXl>rCD%~TqJ>aV_E~Um` zPeJ13T{yf-pZdYk^)5|)&yz1gp;UM3uR8e&KAN2;VF}Z#8_@eBHe-FAUa(Y*$XnQH zO*H>Q>d3q>$33_EJ_Z_dcq*|-ld0gxztu-o?d_X9WQIkGyeaeIzF6vOzbI-;YhI;~ zH4uP3a&FIkEhAO+T5VdSMd_$;P?it78FwkOIeDXZUJkLMV)TGgn5GslNOlgsak#K>v;b7C7N$RtTS< zo#Enw)b=Z>|C$8OTuu-vXQy7SI@5Iyb`*L<%rENdf;={C?95ZgCYyN63RgRz z_kkPTGTCQN_d4(fm!Jw^7y`MNozqsk@AM`jBoCF*;f^j{0WSe2q zvd*vUD+8K$?Rj>d-5^SzLw-P#il<+p&5cgj2DA0=JQ_Uv4%wi08c^;iK;&2%q6v~- zK!;eJG7-T(96Rpk1JNQEMW=(D#1>pj(C#lMxjHuK zWLm9z+Hbcq1BtJ4+Lur0wd^1x$&o~~!7PnHSeTDSxKQ@cHGG{9ycwNSC5O=dwl5VyQ;VI-(meN+vv_ow9Q=$%uE&n7~_Gy(JyyNRCoe&vVlPQHB|j)9m>N$z`qGW zVu7+q#1>fI;TK(7d~Z@xm*`Xnr0~TubQPu=WSq!ei!ELz#&g>KmxAjCIKsP^I6@>R z;B!L6he|qTVq>d#%YkGBUf$Dh2(sEXEgRVd8Ucx^Y&Ced^7n0D>|h+$A)yH6OQEGd z2>6^K0tecflvjWlrv!3w*SK6@Pi@-4fp=`>4g^B$o?Qi+#e5(|JSaaS5$zhw_@$2< z2b!kPgtJ2$zb!-+Np+d=&r|FIPfBHKZ9pD@DY7&w+5q|E@xA)j4a)X1qMVbUq>drL zNJ~-4YHFt3+8)ByOsjqC8M(Y12W`VHH{>a2x1^c3G3H`?O%?p&J=#PeXCV7jfkc0v z1GK3e5}QT)33TPLhx7|B1Gopb;7Qm$pyhm?mZ#)^`g~N;Bo5VzI4*b*e^%oUW4xMv z^#v3WiCM`EB{v^H1NL$H?k{yO3LAS%7gzGUgXRoML?Y1RVD!sJrK0K!F8ae zQTaI3N2&M;palTKBKQ9;^rgTXV2_b!0rKnb>^!Uk5GesJfs1PrFnbv; zm8IL4eAydDVjwaZ9}R+*?jnfG(mG}ENwA@%2Y3L)_3TSJsq(XQ;;^AafVvzoiw8Uh zNS^>$Q`(Dtl$ViB1mp~K{bj~S0+Bu!9P4~6mm^k5BkUsxpBSkQR8s6|L@C$r*v#uT~WP3?C+ z?5;6<4Ls_0NK3#fMV39v@aDsePpox`wI)myfus!3JBjw%`X!|No-!iFHRx=ME;N~; z2#LnbKoJK&mHerf+HW{ucmL!!dYHf34RPD^`ZH&CZ6xY8 zNq*#qGcDKoamx<_l5%0+-=+yZsz$gIz55#sK+V0jhti^iXUFS>bv!)-b+=SGaP<9k z=6Nh%HRiao zZoiW>hc@V*+MNDd71(ws>?euI)h&GY!FF{*z+luxA$pjwK0u*EetXM8H`d_@y`h4| zn2OV-cygG`*Y1i;Fm?K23;2lERov(v=gIl6KNMp-ty^atw8=fXnsHw^CwG@AKKvX>7#`{^v)Dp8&_(X2Oe)V5p(V#?nu`>-Rb=((W5d&OBL>v;sT zTVP_^FlQLvwP~0n8LlL4(`S{M;%9FvQ!zaAb7O=Wc8go_nYcr;>qymoyBDpmu%-6> zPY(%?<=E5d;kzNT)Ms|K{~)_iLWMod`Ehb4PxH6+@9#{`_VjaSTkqg;g`-AGM-%Vk z<|otsM!+ss`-CN>O-O$vM(LKsuY^OFk_?hV?OBwEVqQ1+I+m3+?Ja=ppG=CYp?IOa z0Q=5udyDH5&azE%j)phl%@z%^6ixZ_P67Sv5{al(? zJUdx)#rP8sp(}a&T)*PSm*sI;h%t$@;0gTvX!-Hd6qdgmIWj2h3W6tf@-fLDOFouE zztUJ6^~tp8ZLzvCFgoGt1SU!cM(k(T(;`d|8}K>qvV{|!aPJl_(1Y}-cN_BiKLN~ku)-q3$d0dd_^FW;pqCV94vt=z+3C%6}&ZA)jL@?PhbuYRZ$ z=;>>IKJrrWUS%PELH?`lytb?H2!X!7>VsuShRoy{V0r!FDl{j&!iyd#T0@n2Y)*|0 z2zNE{4_OwpM86z;GVO+?LO=I`1RA0x9PpR7BL>;(+6*T%*r<3=hh|5-CRl<&G9Vp ze&|A2lvzin5PCgIr?8W6N5t3+D7b;xqM zFWrF8Flh}D#FvTUKr|+OR4rYFWz5tQPNi-aw|C{k(YG%fJ!Eq)18B;G4BpJKG+=R! zfYM7^vvXaE`ET**`(3C+2qo=>DR^X#FCsJ&LMwXaYxwWJbKHVYyY|*|Q!>1yM@TC1 zD6GEpEnIF73H^vIAvfRDz&gIrC=mnlOZv=z5fukVJETyQBdk(jt&dh=HY#XxB(r<0 zD982F9tr8F1Ht5NA;EM*RCvrbfYBGbwjI5GoB7_mu-34UQ=fisosBW{ zoX{hreW}6N3?-B7N1fAS)2G=h79H8luPkR8aEl20!R~aDTr_M@kH*op-Z#sFKKg*Q@ik*zQ@t~j;zxcDYK7y5IS~XePlvbxG$AugEG)Ppg zB~J;A7u|;Cm7>%bSE^?VG2IWgpEH23tTB|Yy{BgIl5zEmbIP}kUYHR>k4G@1O{ z8sm~Zht_@YmG<(>D9^1bq@G`~vrRHH?PT>I zA}R8vk3+Q_-X9c7DE+pjvLfkPdj+zWDu~UIWkKARV_EIRl8DzhK~e7&ZiPvA%AJ@y z=5A&6hk5t>9dp!D<9Bmt+nV1~RUO->R{!V%KQuIP9w!`7=CR9HK52*OGug89 z5y1U;HX#gjdDd=HuWadPDE`dr>tq%AdNJnkCwgkzsUE-Hjrxv_Wvvw3FumFvyv15J zO9D;4^{{p=tZ^d#ukG4iJ3fhi|BhMV(N5Hci9C?Uwwa8@BM;7fMy>OzaJ*27O~|ce zxVQIGL*A*uEsxKSAL?5`1)%)UCfiJWzmjj;2RO=OhQU7G5qtXmux&M~&*08I$$F!$ za$1|>ltqQJgc9k4Rp}zp;wamW73ulw#Ou8krML=doCRpydOfR;e0T!|c1-8%7ac>$ zHP42`SC#f%bb2q~bv^ z%a*oPEE*uk1yz8T3sN2n9`4kM6E$dw2E5#UNXA-U!$bcVk`rtWkv+Xt4Ex){L@hy%tJZ5A*{0q zgCv9L{i=5nX&V=BjF!*zrz!@#a&F+mpj9~$Z|Z)r#cY}M3uo6{e>E~#vaROUh!m2p;f z_fqBKbonX*3~3L5ppAMp+8&p67PIY3g#wOK87A`MQ*zOcyQ$N$sUX2MF;tTAb9~== ziHucj%4v+SdsOhTuA9##s+7?3VOvB6L-KgF>f)LcoV#149sM}S!9s81$xm@c5!V9& zJdecs;*_#!%ItWJzcVtrQO4^{Cre;~&vje3`bU<&@5+Aw-O_(0GbU977Z4Ymoq~zP zWFux{NXGPgL$so2U8&D(8^Qf`#Oy?Ac?9yDa@MU20l!TgVn<8!GYU1YBQ^FWr8cu! zfus1757jK8=HsBch^9Z z;`dCT;|zfrosVZ4nyQQR$#Ym?CBWn2*=1-z($&a(FXFCNt4v(U{3F?Sj4Jrm-n*^b z8hI7260Y_&3YNXXeW%}inwht^?nuLzl5kpNxV{(%&Za@y&VX6t6gDijaYjnVU>JxGpqO3L%s|9ILZT} zlOJ}d;S2;`pA>e-;-gmO)8@+jg&4xL`Rh06_=ly6m`$DATT2>Z_ZOl@4{`^cpJ&+a z``SJH$RwT_k}~m>4KBEJC>e~Bz)zSm6ngD1DgLu|3NBDVr^x{F&>^40p4`O-Cz0~1`F}YM<-DLI*VaPlfd1}&RjLT z$YD%Y7|sNFx3i$DK}_(vnAQv8s>86Q*kZd>!B%LPho{J`>51?2CZ*wQL9KFdxK9p@ zE3cqS@ED2lc4cY~ zO<)qd0z%E7sFmj}>Z_`3hL>Cl$tZifXekJB15-DV>cdla+Wf4gFB%+uw3Jka9*%N# zOoWyF#+I58;zrj$$<6iO>A2gJ;*9?bMY(AGgS0Ns`Wd__YGm(;VD5@{|4P)!Y@su5 zW2AQdg5wtJo!CNGQ>OSNeDwC{w<}?Ti8KiggQ?d^Q*vHSOlB$h?+cn+f1iiO=8ON{ z=*_XRrEhLNRh)fm07=Own$oqdpcE0#7;JywYj|Avd4H+xdeEPI!rl>@lMD6-_rdhz zRSoK{jT7Ycng!@Op?s6^f97a(7BWLqW%>T+i@)LEW|CUNb}0h>V~9yUJ087%e(#7CwI(4u)43v4N*Qxipx$L{ zC7o$czrtVX_I18_>w`NaY1ndWwyUo4f89zAo9&2sjguUl)VlzoN!1{^rMb59pv{R+@C{v9^^ePceddCm}sX&xrlGulv;v&KmW zZXPSyU)Gq$eNnHI>OAvOrlJStV{x7`xT)ImbFR%f)y3!5i-1*O7|mLx)wWa8u|gaF zQvBrpq7x5haKTs&+ReLJ~h-u`R9%YGjt4pkl; zpjSHl&9g04weoPc>L|NBQqm>)9@*lX?LAZHGq;zP3n%>lAX#iI(`Y5CwRb0$&{UqE z9cdKT4PC$HFkiHB!tW;h>ERmMfujt6{6wCw@% zb@Ein8?*Ys%7br_(or)cq(}S*TklEF6whFF4%db;ABx>92l^&ox%)Su7qs$>+M#2D)iXOCVh{0{oX=*w>o8-Ov;$aHcZvytVzRvtlz9Z{?5tZ#Z#@~ zmrQiTrANNcXuCubR%~r3U8}@f`~3%DM>58m^v_Bi;HP2+wyxK7!?lv z8u8rZwgxgScm!KC#5D&?!yTvZZ37>rk?8ldKTb~-dzO+?S|0^!%uF;y2!&Ja*V*Ot zyLpYCOcX=p*C%hAl*sk&6LgnbVuUyIxH8EsHOF1UNvF7u(T{b>IrU7oNFcrjt_5fC zaqWuwUS8hs`}>XCX~%Y7XZqhYe-rrMoL+Tm4&R?_khmR5?%Rc&SvK}Q zY1(8M_JZbkm>K5wON~quay5NY5o7?F0Y$mezfQ)uv<=4Jpxup@XK*^AXhdu}W*Yl5 zZ)rK@m;FaYt-m%BYfvlB)|10hCwynRz!G=F!q7m^qWMh85w!TYE_ik-DMECAw6P}m zvNn({N{hFFG|`oA+A3NdV(TcQ`-N5ST{UmQU|f)Y5WaEp!iz#Da06odc=@bq1xZw} z7$WL7szq%AX1e@q7x~0@G>i3&We(qNO=IdFwC)~g@Z-``&(g2;aDrhsQ^I5goZj9j zL}R=YPVK7qlamNwc>pekj@Q_uenC0Z}V%;PL727N089>g0ongi>ZL=iLWoP#{=hlk?m5nGMl%?%xGU6wM8BoR<4( zOJ`Vmn^uY;2)s^B_+jzAPVPB>u2@KZM%jV3S#(M>gh)kXILE>g*NKRtP$}Elo=ymu zRn?wSL^nF_p7&h=$X*~4^ufmUO@|tvT}K8OSWP#GqIf<}gw`hyJ^}rBc5hR?X4hJL zbb$!BQ`_oU;t-n*nx4oN7;F`_Oph@+^3P2Ah(YR#5;9OP>Q@f2D49OYUO-Sg<^V`c z^_fSX0CpK5dM2p`h9EQI8G_x9xPAv{Pv!$y&w%EYB&u#)L3wgN$lBB(RFRtGnnW65 zda>J%HQW+L5KU~7ZQp{OefE_;mm!FSR+Jp*Xyb5y@E~dFFz0v1umJ;ulqLxbq`4qv z_CU)kz>Vt`Vmj9VLi(T@n+a9Dt1} za{xMhIgnZK2YLo?D-r46c;LA<^ZmNjna$ng0qw{kpcoy7q-`Il-7liE+|ichF5Har zT@>3;a=srA4tpk@)WIGLs{-y|BXIb!iRol!(FsCkk$1Kz0u;8l#urz-p-(1t)kRrQ z+>$^7vzQWSr47M&jLU32xdm>z>O<~ zt=J2Kb~Felc}+OX6{uB0v6%oflpPNi>1_llmn%RLT~enOwY$~wNO_(Skw$+6^>@Ue z@#{*~|19fTmsuetpfLv6DsvJ!!331#h$#jZFS+H-?6kRoH`7jZbx2_zlnsL51O@MC zr=Jz<6>`U0<+q<<_-U_EiE47T+j0_n)9H~see&L&iTj53X4@@Sd$Ri;K*;&XnZws_ zL&Vul8ZOdDoX)4{S`$cpQmXRo`U%YS@||TPl|dlyDg~X#R(3ZhVe8S2KH`4x13szu z6Yx5%p(Oe4A;{F=H&Oy4cpK_AkoE#%2V4b{665AqJv|?D4irRSsAML)nWs#22K3aBHz^?K_08|Q4!-udJjO=9a8&u=_JAiq~Ww%%i8=WJ#WpTWSb>z#+U&b z+X0+Cs)&NLQujd4*DCx9STIgxUJ5ySxo1N5qNumq@ClP-JxICBSrp51^! zc!#Xw?xG-6IWVs6$%0r2(Si15?2DatkpUUkG6AtCj{e`Pfb?Oh64D8GG1Ke1f^59oRBC$Rf$Kh2l7j*D{3wiFEq zH;nkhS~pa$t%5YzmH#89{(sa|u0Vh_g6P18CLml~Hh^ai7We<4QAS|p0}&or zlTDubm8`?83KLJ5YEbX`ks_q`F01Ouk;>pa0R$T$m;s3SWg-rw89{;!v?_81YHI^R z>g5aGMu6oHXsY0pCV`8~*$u862w=v4zk2yGc??bxnN{dz5c07a_>gG>U9~+I94raa zrCOe%zI2wGDZ6^g!WF$wdwS>iod<-{`Rdw%y$Jq638A;%d zN^l%Q^;Wl`9S}Z<(ML7az6CQdk9gM@%!f72Ahpa7sOz7)m6p@CQF2I=0ixyz97u*M zA%Tu6r8w*9szW_9El2xHP+P$n)OSq>529q%vmu*?CxQZw0cwVrx+;u)zbc4@VVm`H z`$(%sE2z&dA)%AXPT;R|*tER>9tI(cKGOa@stk;siOMNd_{A|{`7C(C%3EO2UALS4 z$>Xv0JNg zEa!I<3-KQ*@zf}afM0vtK5b8p zKR#-A$P(g77v1)IF{r`V?ohfZP6TfW(`h2pEEOTh_a>_QbscuUT@D>2-U=(IkCm%q zv)Z2KaXWo}9ERyT+zzJeo-|Q$n2Z{iiOZFe&F5a&x=DBpV4n+fTyO+o^e7jIE*zpj z<(Nq8DdGrmr?c-ABuD|#Bho8Ri@*hPd=QP@bfdTmz8m&3Z2T#X+#g~pRax4=LT$fE zhx*n_vwlb5F2!kB3)O!l=QoZxw{HPo{XL8qE zrM9n}IoQiVN~*!zeqo{Zih*RYZP#E8?8N1p>|KUii?9Fgy{dmlI1;J`1*no=HBRZo z0rXEbPg4-CIE*%nWivH=qA zy)2E!5}noWCK9Q|RNLMQ*1j^*X=i3Kjp?Y1jqsa*oshSofm7L<=t%OHs!?9eD;N)x zp?u25U6vA@so9xKqmO-SLMe7u55{H%el>koNH4-n z$l8j&v9l}k!hDFcKf~KaA@oBqJntHe22EX#H2Ehu{(2-wZ0Hnnt-BxpH#zpZH20fr z#NVjkgW@f7mi^VeUv=9JB8_;X}ZI#UrF5%;q2>&7`Yo0#?J+?I>a#S5R|Ic{MXf#j*xeQ%HtXw>I zz1qCzm13b6X5ba$wIIE2s$dko&Y{+Qz&xN7(N@VrH|eS;H}Rn8W_fv-w4?PT+mlf0 zxkxU&otS=4SmEQ;O=C~>f^wEFM2LxPOZmjrBF>4EYgJnhtD{W}Qw6RVdj< z*K5$p-*McTjhKrT1gmS5-QW4Rs6F?r-lJCyR;^$e5ZEXrBdaA$`(v&4ldCy(}Wf_q;P z%pfvrw&!Pe=uOA(EVW)aOpir9Tr6)?ICxp{i(G&pntQdtVn9X4G1IM6GhktG>{e?@ zvrh=>P^CFRH)U;91RMFGJ|lTfGdU1$Qw?4MTdA*-_e|C~t%?jh_oumeu`G5&cEaZ;E?DP)B_{v>v9#P#vxhyt^WXIl{&orIay2UnVpkJ|b zZz(q!l31X9``J1d8c(|=o>qFu%S#-+h38nokb$L6llP9#6?F+_l}7DH-@y#i=8Nz% zqUndxK50f;0|awV4{;NE>|3ZWc3OcT#iN0{!I*ZMIO#kKGKt*r()aineBT(i)qjhe z0vubxRv&R=dVPK`RK$2BGt^I=s_SGW-0qece6g*rHh?QHezwx7yy*VIXf}m|Z_DWcqy!Y@*>mH3sfA2|A4z@h$RfK=? zGyA`1Jy9vm7&nqS&4k8LXa6Hv!s1_~!>>(*2c$d)J}x|X8VGMfG1Z@>rdx~8IpghQ zT4k%hxJAop@Jr1*r!MYkp9blCv5CHW92QMX7XKWV?K7WyN9Q^J=X*ZSC|crsGI zwu3kAm+L=4?=*laY57OhcxIceoq43So)&AgMwwM5K=$f|j+fSqbu~R_z?e|2u*A^} zn8i(LwOg-T*iL@{-xa}2fHfeSvre|`FS8Beced1xBe_2YOSGM~9A)}@&l^fkwRlRi z?QOMLHe*8?uy^uKz=T_%VUR@F5p+%DM9Ed@+!qMg2`~<)rt4jMUmvh+pPKkrPZz^| zb&uhEad|jfuC=S#*ZS+iAzEGGaWlr6LwMXP`D`TL%zmMVchX7WE=i6Hi*?ki$1NL! zoiZ~+Go>%4;#+x~7;x#MS_N$AFveGZGG8<}g-4s$xyC;ce9iiE&Lq5|e_id?sz3); z_GxqUe^jW{VVcu#{c_18$(|-RHYz%+QG5@)QWAW5y;V=bWvAd+lklX7a{KAAQH5eM zJAvxEg>7V<@Rjd7NaxeN@@2TpD2Ow2^a z85|K~AHozzVBH<+jhi|STv#6`RJ1lVG{8^ZfH=PJ=xiHHV+7R&JWGM)g4~&9pqjx? zx);|J(JO5HjHSubK(q*!)5v-;a3vyF@WeGWAny0{6hkm5IuC_JZP5*EB>D`v>t`95pR@ zS$WQud9tsNK40V=JT8th*AwlfZ%H+Q-PH_UUhADA`~uT`zmne4z87Uar@eK zz(CeZFXOl;%2nrEEI4WBsEdRT3CT1Oe`>}T95++eOE4X-E$}*)h6lH`-$ zXyzC7b|rNWw`eIzHK58{C>^WMaQ?!c+0#|%KvkduRC$N(+6-e=n8)@jE2gp&XFQDm zYqoRHa@u9VTat~L+GBBRUG6?&*~RczX&WX|uZ*)Dk3YND#G;V`!FlHr`~)e5!`%A& zV;w^kIyNno5_4Ia-upj^E0=rUoKm{>vQ-*R@(sm|geX~iOsB%KZ|fXpV86LmgtJbN zdyYNQNwaA~tDDJ;!6)Kt#-?&V`^^5KY=kcix69Du2&9}7Bsc|FPHf#^eW%Q*PLBk< z)A}D|o<~rtR*jp;?)|#ouU8q3VZTGx^tWlYq@b?6_6K)|A~cRJCuIvv-vDx?)~5b9 zyEk>bEYBVLtkiG6E{bXg7GIU8r8&+dFCK2&1p@ftm|R@nDLWJug|TDaC_IghEQFU6s&C_mLGH21`|0U}Ge|UQ9xF);De|Ug^A|X1I zMnPhP(k%m&?jay0N=c0rkQ|DjPP#+7TV&)21qp%Cozf*B-Sc<2KhN|1LwPC6w(C0Q zT<5&gU?8g|cDl1dU_$c|EHW*@&sHUasWF0VEvOM$7=>D`Eamm>LC^mD?(aThNN^G0 zQHJ{*UPj(rBi^%-jPlf4lRv(45IJQu3D$3$xa8z*z{GN1n5V57#+5mx|LjxYR%27W zk9r`h)j7@YSGbfjICgA4pa&QH_(5hD2>B$J91j>iuN|3mw$nkFKWo@RB{;k9R6Du3 zV11B(#7TD<{q;s{exsTNJuZG*fu-Mn%;1LdbgeyRkfCdkzhy}PcUo+5I?%AlQFbfh zV^Gc8rn;y2XQd-EGsfW*a<;VadJOf-`q;LKHexUH;fysIJk}#ZgQ+Uq*14Z^THasQ zU-#}|4hC&@O|e}QGmv$2eey~uE5=J>#io~0pXT7aA}CBE?axkh71&Sc>ga=UA&p{~&cu3nnVWOPYUvnqxm( z?bh?|md(7el9>fr>Ln)XY!`yW2ky{^0cn_?@wrq}Cf`!asBsUA)M8~ik7PBYD>t+ybS(Zh7Ad?=1S0 z(YgL)BCbqi?Dj_WFL^Rbs_72K@UjKtDp}6=v&(q8aB-l|K$_SQmhA1ddW@v)KI|pc z=SH)h2U;x-vExWD80UN#>RgK8cGg^m1W2_#9zO zrX8BMb+7{6bkYmk?m80^(0lHhtTh-m{60-6=qUG3>HVJh;lz6J9kp6OX~KSiv)DR{R+^Lo50;gj_$Qv};aqKr-$PyTidopow;5 zl4%d;>*C9xDiJ>BzBT$tGd<1<26CQ(AX|VCC zgYUgYkXIo6O29Uvz}=33WacxCd;iwW>3Xn1Xm(IXrCOCkG%!>+pVf`k5O#_JJ*~Kl63oxJphxdoU7f=M(@gp7p zq;*ha$(lxvNbV8+s`5LPjX==;G_uX=41>ekKos~=K`~FWdF)3Kn@8xI?bhD4T7;JZ_US2 zj-1xN*CP|TGNZug=7Gdi&2JY(aS`)+#teQ`sKs_Sf>9$UA`nAkB zVfk;4)7sVmv$~AV=3>V)7NY zlLsP*Ic)Mc!~ir}Rvl!fY9;;_gsA@p(sR1JS4-DdLAKN_Y2`v1(~y*QyN~ZG?|X9G z2j1)R6(9H0r>+tne3eRH*Fdd8HVyyCcK1sz8&_KxnkcAddkrf7cP}TsE2J(4wvP*CbNc%5KgYuBs_nNS>*V+fN zBcmOM9ri}D$P7Jw`T-^ga|4bK#mRGtY=Cyj17tfCM0Yu>=I6wYdPvgeDZtDQ^C84l z7ZdW2MW9$4g8r|1a8a&^U_7^tc~P~aS9ZEwD`N=<=?n;Sx|HoREu{n<`3-7h`5?#7 zL7LUA;{r{Yg9i%4pUndxAzixz7Dz7hB4tmMM*xI!{VLB<{*^ME+`UFSNE}~iN_SJJ z;-U~!V?Dwb>u)5U4k5dm#WD?k>MdeFT=VHb=iCx+lShI8K>l%zIsi>HLbSbSbGFWj z98L;g!12-HH?M#Id~v1St@E`n+E)Td&TuNg3sIYOTm^bBRoXT&i{M^@dq)*?hM~Y} z0gKa9rXh)w0+8AUF>)*7zF4=Cjv6}!ybJDLXTL1f0#Y;t7$>HXnaOIQmyM9Q^Itsu zMgW4mqXgY-daybB!P`d4hQQS*ngqBFV1l-`zvw(BN+tpr0#$I*TV}Cw$sh|xN0#jA z;F~-`HkEsHf6QZq> zL!0sak}698-2uWGYC33V=c1|rIyGetJ_tKkb{;5iP$cV5OZxJMK7ipeP;4$JJxLW% zRIavSx4~qA$w4RHum;?MzDHln3}8$X(mpnldkjiUbpVhLU&=yTK_TlxDrx|ih9df| z1n5$z%4|N_hcq>FSN2YeSRC6mj810<1P}1A-5l)39aVoBG`pJ635-9dUGywp%0$S_ zv1!-1@Le8e^S+Dj83fI4o!`D%iQhfQELnddTHrAa_no#YU`_73on;Fm)j;wYFyQ>J zr3`#36Z-#^pMjfrc@MvXu~>qmQmGz#R(#fWmDC|YdO3Y`KYzdIqduu;nCuwUunXGm z4?}q@Ab0NGfg%tf`!A=^;+1CwYWx)sD7VtXv2>jwypsJYo`*ZdR%z9XXV?k-QvFsn zqOZ8`NWt#@T<`|wZ=GP=S@tK1gHki-%sU1(ePr=sUA(13LHn#@EP(E=#%?@Vs;hvj zfV5&dT)*j+)LTRHOV6h-0{09(>#Ua0TeTm|7s)>nx%XzID@a}@bbxTWK}co{;qb%p zQqe7AFV)kJJ@D9j5ul4gUH;PfwT`@`Nue?1Fq=#N4qyhs90hETBnZ}nt|K1;8<>t} zI?3ffMIic>uVmw-fqh3^;?j|HOO^x_-EQlCp)m)~JCc-p8k3RFT>1uW(&a$g8C07; z6EGr|{bqA}zL*(Jk4(}UkuF6_c$(d44^Jj@Z!8 zR*-v#1O2KHx}3|dUNC9E`x^`rjpqm;1C4LE%NmYr!vApsXvlNh%SH5hw4w%w!b2#; z66^s~Av?DOI_-Z45Phu5%TW)L#4N!M4ebzx zy;!z5SWZ?Tf((1}sm`-cRA@rIHGlgD=l9Fng_>;^<(yS$UhX)zP$l>4HqQ&nOP42C zSw_S6lDe}qH;J&&@(Y-tO?EnkJ(Kl(ClOS$#pPF9v-m;{kYw0>GJajoR$U}_4Sq^& z0bErY5sx&MN5;)}=c_AM3T$r4qy)oNe|qvxCXZGVexY0s2~QqO-Tw*irYXuOU<_D z#)Ja=jL$hS%biblV`;d=(%qxhzX9%{HPd^(S8BKJCY;l-D-?ncpz6@`TM0ID8#Ivr z`teU_tx>h`#sM|Wm*CE?Ep3*Jn@nPqZ;HvZmu#UaVa+pJ-z9_|+exgB$khCUI1CpR z><8N44gaG$_J~gtMNWN6KNs@Bb0(|XXkgeyq-K~Sk z&1YI}Y!}PDqe(#t)ib#mno{+!+oqFP>XStS4J&_lrQOn4`G8sh#o7~Z-=5hH19pUx z5a+ami^_EP|u6v;E#}kv#dekvuSxL93!3|=(c7m zxUnv}9p{+VA`WjxjTIs1)eu;K15vsHhBB1$o@FqoJkB~rhFMG=e?>KHo7fO-%Ebp6 z3c^W>>MD1qr)VOV#GRozif?50 zBSN|?>ULR9SMyE`^iP~fjI&U#kVjs23l^?nK*PGIzm--{&f_ELD-FbSeVAQ?53Y3Nox*e(K?uLtvB^eT=(|w_$F7C z%B-5LXl)9{l}o%^ahxzl9pulPlxD)OH*Z#!PN62V&b$Y@=AH(rAF*qKx~tG!{F=uA`99ys`A zS+y&=*{wM!X}!;3vxzjs`>hJ8PlerZ9W@#C!P3RYs*$P|@y+DRj9mFDlQy8OJ2Y&@Vo8@}h1?5=3rn9dH( zCNq*1jTg>hXmm1?m$5iVztSo}o8@SPl)h)hx5`CO`q+19!U!Y|w;z@7r>C{0u?8WF z)+Q3s5KXQ;8nU;^4Wa?;pO;PwtfU&PGw+SAJ&7S8hGMh{qE*y@pyOHCbc%mwdQrrd zO|@fl#t)`d!a|Of30#f>3&6dO@^+c_|`F}|F(yuy;COIok zV(pO!n;Iol0)`|bCoV@^gmFu|Rmkm;M7hf<`JfY~k2HObTUwoh-7XmSQcX@rJI2|WsNkK$4 zqB&!V$3MkR06<7pOX-9PT&+e4uyN^ubg-dS1uqv<-*+v~b+ayjA#Hv`*-b5~q_V&a zfHCAc=fX9>ZB8Id64DO>0Qf*1A!LfBK?#~AWz)6};m2&p+gdw#Q|`z7AtO<$Z3>R( zQ$q{Le%w*}78lL&_7hrNw-(4|a==+k`-k5eL3U0ngo|{WPb%I?6P74k-$&SHaD2hl zkvp&>OF(os1fkPhZf80L+0rjIFWZ{4$T4}>k8B|KMXsVI@=(|*&s>mU9$=(SCL{;W zoR>k;l+YLuA_u8~dq;DGkZ}=wM_`gjR5*KJotj!F$OkcQ!h=2qKVv^)xl$gXtE$uLs#adTw zp%X)K1hOAhRJE=6Hf2F6IU)iMY7Hq-!DwxOXR&z46TS@{l7R<3Xn=SQsCiDGvkl02S1^sc`w#L8t%(YbhX(L_>IAB^t-F|a z$zF@TSm*kYu1%Qf)zlgW1B9L{Q5TPSGQ*!W-p;9O?lT5RU)TV3FECjp|xH$F1p*0gWLJ3{iR@SL`EDw5`q4CVF?Co2+P) zO#nckgzE|*Ri1EhfU#eJ|8^8wK$#dcJ8EC~n9+D3JU}9R^HKsxmkwqb=wyiEA_srW z;y^=geo@W^LrXlnBQrq84kEKjx}1m1jobsMp&*Ed0Wtre06}vefDW`^mV>cl6haRa zUtBm)LaCEPiUTkU0XS;?(FLF&cnO%ZEkRz~6b2HeAQ%JG1a2xSnovkE8liBR4+8@* z2Ko}O3Y2TTD|{0qm9&7qY%+*D6hujYo(!Pox>S|%W`^^)8wh7ig4zOzuHIJDF#5|Y zq}*$Nt+pHj{n-mUKYNu8(f@tLA81o#gH?m@|N0DJU|H4Q?>)wcPX`pnx@kx`-2+q^ zhp@+U7zH>{pReb)b2oWr?k|p5C(do~$+xnf>7FF4yppm9HAP{a-P4-gYzkKvqD?po zibM`ZR;!iB!fs`p?&zOVPfeppTF=Gyf{#MXYkf8(cpXz`%<3gbbGN;x|Kcl|iiCBs zC$Gwc|T{-q! zd?)s8mV=+tZ~M%lb1hFN)T4UsC;FU|d%JIbk5J|mXys2`%TbQD`F^ccm)#@}{VmCF z?|Zb8EpKFGgl^J%-{IBgEDCjF(wxoTf4eGYCzzF|&Ldy*Z6^7BK;PV&WA!oA^=hX|Vh$+oVOCxYI@Anj@P?Bl zKmRaKL2g&BxMSkw3ie2GwQNayCu}w;{rFu*dQi;5l}!lnUQprrBfEr8NF(XgInw)8 z63Hu_z~?EpIg^jgBTXj1ca!!e?D9x!%(ca4?mDo&aMoAmx1s*NsN3f|JiTs29JKVg zG0n+|F`-l1*YU8FX+CMhjC+|Qw7kErKc7h~NNL;D&j22)zY|QqJG$`@-(?`pE!vAc z`ySpC|Fg>JL6+s8Fl1NClGjE^h(A>EyjUxveZatDLhQqm>9HAVb`u^exZNDbM`y49 z#pOHY)eD=U2hRJLwb+a=t*moz*(T9Vxnr#!bC$8uE}J94A_WSJWh(|*BTnGY%AhW1p9l#m&pj3%VjSA-xCgCT0}R|K5gq6iHwft1^q4e3ys86 zhTPe5?y_a30e6lu{#dvZtZ60)ur%j<#~&~N$QHU8dNIKT$;R<_0G zf`kAacc!dx_d zWCLsu1Ic|{?Kq*%(x8HHG{q1wfi1^>dsGDoA^^09RPjo~A1#%qSdEW{28FYz_B2-7 z^ZY8AuErok!bnGg@*ND)5xT)#5aF0x;E4d-4iIAKc_?NAA`5fT=PNGV+B-D%vYs4$ zCBlTOY%Mx5;IG#RnL8E+T#9v6!0lK86`+9jwt`|Qr@>)NBKyw^ZE3Bh@C0*NAHkS~{kNXHi92sg?l3ZS%!%IXXk|5X85ibS- zqVJWR_X0_QUGBYv))RB?1FRHWjXpvhRj?1b0%}u0x>FV!$wx$vhQVY32x@fo@=fuB zSSJopprGyuzD5hL5P2RWn3`Hn4*w*s1i@BqFiO#^ZtV2wYYc(dgeCq==P(h~ zI7|!$B}jhjnzk^x+$)it{eCmtE~wW{9@Z?X`5GLyHpFWp*FR{K0H1uBQ2|?=`AqJ6 z*`cr?8v-HS#}c2ak-7)@veQaD>J%?aOccUliQ;%VnY1}oU%7n7e~@gG*8s;{0Tq{A zIr%rccyK&jY(f=LD$=QTyh)M#T{?_gxx|wUCk|=2w+W&Hf{(^n){HjiliMw7zh$R> zVIJ-wwE2}y&vgAbbvsT`rx%sr_uHO+eQk?9a&al;)56iIy;Wp0Oq#jFnOf4pfiBIjl`+Q z606XXhwr_Nk4y@S13V+Q7VjS_Y}0}|*d@k*it4+)e*pyt)h3E0dIdiGgqQwPigS)+ zS;$F&DVg6oF%M`=(k5~iqrjnc6=9~T7hB-Mk%QTBU7i5DoSoNR?Fo3Wb|Y=Yb(gk< zs(5pUY3%ZT`qf`21vUVAXNOvY4Xfoq$bjFvi8kR4F+~4cKnMP^6QqyP2~P^3YEZ)r z22ZH>5mKw23nRcLlVS+8%zL9DBzKk^ZL-knXb7cEPF4~G$z?i(NGG55Vbms41)V!c z>G{M~2*^$BnVo~iE^pA<}8y2r&yY#U#Ri4!Kot9i@{x=xKw*#oRC2>s?3jP_V&NbHp?H!Gshw*B_@0 z1sHMB;<>%9pYt7ireEDtYo*N$pu8lUVYd9Xxs17*N5%X~hYZDF(0uRR}O>tdC z4HW;h=74}cV53L^?CRwf_5ZvIa4=C3mf;M#N@0!3kfTLpu%mb4kIEQV?L2v?iXpfP}x@7(5uXjbcSDHkO0+_&IWZ)W z{?f-K0gm1z#R)f`-88mxZU3N|V^p}D#yHTL#y2iB3WWsG$>`?}R-?QsR3hsF2-MJ& z1``qG>7;EmU=T*`>AKp=rC*WA!NIw^c7ekWl7nLxpAVoHsLPq$9eRpQ1~5R(|4&lI zVCcd5?(+K}_6|_TG3kKNQjK1k)EWE=&T3$k{x?!>{u_T0lz93wH+*677d`v%1M4Wl z>?b_oC3ZEFCwgkvUZN3$t;;Y3iG=iUH8-wS@7*bLrL2;QrtqbE$M!!@4_GyUB*qRP z+S!V;(=YYxW>Uhd6q{y*6Z$8P)9|teW?O;JQKs7;uQ^fS{y|I(P7R0+9=v~$9VuWy zvHd*ww`fp#tmbj~$!My=QTs>(`OUf;9(dZf=W#i{3h?)PFEoGb=Vjy)?1txvYyS+F z`#Sf+_`k2 zSsdR}V|EziJdZ_P1z`g3arm*E!wAOGukd*nAJAmkFHYvv3EZr-OFygSJAuW$XOG6KAsb8&*&79$ix4__3DOB z(=1$9OO-YfG_|hJ&yyNj+0rPph#4(O%ePk6CN|Ykfw=TWYK9jz;2i1Zf4?2n88tN* z!c#>41|Emhab-p{17aL>B{AP%X-WVZcY%{p=GgH!N({jDV#kk4;q1#c*paDrhiXFKNeWk;Gv#qwQleCRziG`MIb^Vo9HRDdK84kM_ zl(Qz@r^76Ctd1DRkRBlZ@=_9pRArF^xF&xgM_ zYQ4-{rcj@wO@o7q+WN0rK2H%n8zp-`f)5ZgVRK(;P|VMEIBpZhcMDb-FP~gnEp{NeOcb~Yp1Ty+ zjtaN$PAWnM^(GmZuU!|%P3mbInsnn21g-j>uG(mDCqd6g}CDuK&Wn zX(009bwB6C*iYU!=R7@w3`zq9w$x%?OfzY&A~r)N>y6u14N1>>enijz9qSTPu)EN#~bL z4T)F-V_2x)x}~tULa|Q6M~y;fexbpw5fkIraFLvv&%dTrxz9_s+junltDa?XuK;Bs zfeA@Y;p|lXFZLGN^ET69k#>rG9AbbKMLj)kf5S|)V`Rh8rFMbAUhH|_#PS^b5P{&j%43!`^7kdOmNBFi|ZPq=5+coWjuGc>G+fw2~|K1jXZ9kA+*^O*kOEORX zYUfdIdn&RX_ikoJowA6Iu;#+GM~Y9o+YV*E>Uv%PRk|4OL8VyP`!l?o8BzNzjEZ}BEi(IYh%^hgaUX58X=k`b`kVfP?V7sSkdcG~e~uB^>i)1L^eo9bM98(BegGI*|! zj{hrJ*1h^Obu&bt(e+z-9{Wp$seJ|tvVl$)5ll64Ks)XoJXWK~w%^W$RjnTB`>w%f z^x<6XqR-rJ`NG>}MwjD}@XuSz!PnhCjf-`7JHOFJm2hDwm-w_=P_N!Dzq38ejC!2T z8Ri{m(!pIbjnm+p+ASUDh&^5rWYqH|b8I%ae_zVCFl)_}DLg23nSjTH*Y~x+mhkK~ z!^bYKx48>;WnW?=aj%c+N=j31=)YEcp$h9=`CedPWfOAi_b*RW`@UHSDJUa43Vu++ z>gBu2ER1j!q+%-9;rv+1#)JC#qj^i5*(kDlx3swhQQc6fV4t5I5h5<_cnz^T(`qI#fe=L82eChA7sHC#Ssn=uMf<*P3^yeRp<~AGrolb&32sPE!c(6l-{!wh}|` z658D^tzG{H1FSdDrpFs95)Se^xc0Uwi}8_b0}FeJR^7F_wDY zST$Q7Kg9bUk7;?_)xi_%$nQm3a+jmd>Bg%0jKsEiJWo_l&{gT`vW1!22nx|pnhSyS zlYjSEsxuEdI8&8qf@KaIR_W}I4~GQ%YZpY!zCPX*C&HingKQYwu*d8qQ{B7ed0vfI z119ke(T2e8zvSnQ~>~n-ta;EnS(MMusjX7l0;CGI24%-`NbqD?D2xpx+Je-$`nmzwk)iKbwk z%>7Nyd`4mOH{n$e9)-Bf=j;!%o_%BMV&JE?Prs>_{useQ}f{GjCG z_D@5_#rg-^VKgoK+hDI@e@Nx-#qho0NHpTPu(SYp$``U+=g{%(SXvV>aKvmBDgXS| z`c2e8vW*v*X7Xz)fLo@=T(;Kir6fXJs=q$m{ zgsBkHy1_8ASY&Y*w$B~F^x_#p3S8;(jQwhrP2kQ#=q|(74a{eK1}iy0Z7VyGm$kh)6eO)-#1`A+zH* zN^-q;d-M75EmT5J&E1nUEtFBMYlf6-s$cJsOS?BnTH8#iY>FD`<29scay%DhAlmlh zxr)|!7PG|;&4S`Z2e`uG!9ff{<2b6`(0~}J`qo+Kth%tfIFw|X&`=-7`43`%U1=jY z7qtKSty0vY^OJGD`K|+;zk`%uEyp#+(G@i&`RyO1TXf^^_&-SNQ%`!meYS`8&R;CI zv<_AN_z~$ZY-~c$%$2i4`6YmagJq`Za0KUb<)`051Ap?E8y%C{!ZAqHGqSy_BJ@68 zf92!rmwE8iQdJxe0i8Or&UO;693$qb-GY6UcsJbBw02u%RppAa%EKuoe^jub_XV*s zA3J^lf7NYm&GaHTo;ljS^12#ZfLiI(Du%GcgW|Ikb7N0Web3Nqq?W&5TTEKrPiDu2 zNh+Jl?AENX2wPGOJ$+)3(=P2f^1-r(hvTZ}m7N|h-SeW4L$3>X$Hkya?|m)LTOYq- zR}jgcERQ1=rNyuiR`x7`c9e3@tJAkR=34sYL2!a{~!vA()^Dehc6jPTHY{yB4+$u53)u`)P8;y zU#anozI;U-TCX3Mku`05;`#Z;76jfkn@5M!RvsVYeqb0Tp0RqLpGeMN`iQ=+fk$2) zm1n%-8d>!O&O@Rzc7%KGC-wMa%E;e}y#U|u{zpT7kEmOSrO!*`XeL5MI~@uq%HsG* ze%*n>6d)qN)_kQ<18qfVH)ik1{=$nG(Ob~C;!Z5=2bp-P3MSm zZgTlB8=(Q@K2UQk>JJ}Rlvpp8lQv1<{8{ew8;_qqJ=A3WgxuVTJStC}wyC%-^r@9d zL}ZF%X8j4Csr}U%_9IJYX72tCgnnscj%a4@o*) z-%(A-!!anp6!EtvbA(t#AV4&auC{&Y;saB@<-;BKN77>GY_c~qY`OJ{hwiQCx+DYx$-(JdCaFaq@(h5sNATtTa~ zskUjv|}LNE8$vfCUTjG}*Q$-8_pXW2{m%L>odu5)G{Z2-g>4 zo_zfin;YFpg0`#J1ipLVDsYxS-2iw>%sZ*)rlyI03@zX;O!*)UFsnk#NIg4g8l8O* ziJyYgiku(+#^uufV5<7qJPR})yHrKRlSBbLS2u{k-*gDl>7nMgoCU21ir*_mj%E#N zNvaSyFd%Rdcrs1qPkC$}^)|4xL!g&{^kt3?Q7{~xjCLXRKLBV1W_vC(2Dm~nz_GD~ z1?2njq{WAQ5#DGX*t20E7AgBL4#ZYSmNGp8R~PUPa?i9WRG1#}#%j#-p+C1|G($wC zlI%5Iug8DzPG`^Z3%CeuTN`Du27#juFxVn7o_A14mTc+GKeMBwiL3WaWO(qQ71^U@bV8AuHE`U7t#ON(rUQKk}l}#`nPd(H} z_-Z+aueJbFe~EnpV!dZODVB0V-iAOxm6%amNS0VUpil;Ad4Z5vlUvUd#01$6T*Yhg zC7fpg1VuCe^mG_OC&DJYq5aa_}XM^P|G%&3|vEak+BsBiX zZ=d!aWOO(yi4_KSm>otKO$bC4T!7&XAW}&(0@1A+ILU}UBB0{7p`FtG!c=hN?U4mv z9B7=aFABGVAUR;pHtF*7A%bTJH$|--5h6;Mt#}qE5+V&L+IxUX;a^6Rc235pl|bOj zsKn$g%Kh%(ld8VoTPN6%9a$WN^ddrkC8C&*^}OQ2>Xa)(HQ0(~;#4_fk+{agT|*GUwkzfx29H&WmW2odyA=f&*dnC7 z2VjzruyxAYgDe8T^mEv>LNNi475Jdv)#+ibpuzzFtn+|`=OVb8vmBx$OA39_X9L&- zuJo5`feL(tw@5+|18;$JML`^9_w+?*Z9IyJ0wN4cpU;uie&Dvl9Ly9vVC9Z2f5l{)PPCeS{aY4WJbxo%;Og z2Y3qzpCOL9Bt#Hf{~*?B_w5Q8iaXBQRLPh8!dW`ACj1Ww$@>C?kak>Z2vnK`0elpzdIj+AW%862?=saiVg(=A;vSq zYCet@OeOon1U(M`c;5p^ZGcTHBf=7N(F2fIJe?&efDqKoTufXi0ebSeubfRrT3Db= zCs0(NgByuYf*_fBOyIWPgf7TGDsV=9Mr#6dlt~<(8$gs1w=Mv@EoTG)aUfjmHXQ)@ z21zsII+3!s6lhTm$4@Ph=8gNS%a&(NB_d-Lw~xTu6cq#TMee71V}?y+U>*W&n2amu zK0tZFmVDiW%nIn~0Tzt8l-z3*TE}1RysiMbM#O)iHc)HOO9JStOVUWwcKkBQ2wX_e z%dSlbR5x2v9)NI?Z3VDCdeB8t14?kWZ5FEm+Brb|JWQ#xNra9<_FAAyk~@Da7+YLW z-DvVAu^h3>b{7F%RtjvQkBjV$f%(9r0%8dCGPekz*-3!zpx}GdFK-kE?6v`0L;UG*f*fa32j|!hyCn|XPt+; zB5r%#IV)DsP2Qr9xguJ8TW7cY)YWc>^Q`9dpm@?NmCmz$EzBOF$QSISn$DIx2&Vb} z!H@!=00s%6anj`6>=OjhmwKw@HfIlBI&FQ;{=wAN2%nd80qEn0{W3U6bNDIr6VH+o zJGv5nRqA4{)tRJZ!`uL&j6Xgd&3KEIg$)Xr*KbKXu^8W;{Q;l0Q=4Z1 z-0<)7tTioYH&fP{T9P{T?3-6CV+%`%@K6`YFjVD3y&5NpZ#rhzws%BYB3gXg_jeOn!qv0}rJyRGA&xjnw=r@^ZXOEeW3HeFUM z$?kTko(|`2$=I6`*ljA)v5AX<8O~5yPA2<;zdH{z<^PoQ0p`v+|2X++;2*bV#f7^n zE%|sxH-mbCv_DU#X1UBI))Y$a-`{o%sFR~vTy6Tn1`2;}i41MjJxXbz!?Y>Y+Fpwi ziI%EZ<&kN5+~D(GWs@`1Z8#cz|LWx5(rs3!_-&#Ko|GM~$+Bsm0Q-jEo?g{}Z{OPL z2{%osK3by}j1uRqcrfH)N_4r6H&E2^3Qz>?<-}Ml?QMSH=r^6Ua8N2L`N#Ku*GdPr zX(^$=k0iv2=D{=)9CwrcL4wQ;?B`8MjBB6cVdX)PHtp2dj>(@^&LN!=t;X!s?F^lh z7K$GG&ox+m%PQj;k2Xwu-exkG?FYL{g)`x_cQRQU;)b+wuo0lt2&N35T;{icG($?Oc1f`wwz6ycgJ{VI}N+K|`*7>+9!YX_&lG zkxr$fqT;`+%)ZEN!-^-IA-(6`sBhiyoj&_W0CifTKttx}r9wc#wK7XcPL-H2WGLqK z3==6Xd}_YrxIy0bBWkUX3$6#B)037_O18r`p-bNMvHbZyE!uVMaKZ0}M~#{>qs!TF zdB(fJ&0<%@^@+an!?fmH*{})&?Ni_nA$xf@t(2$70?z8k)9)UE%Tg~dz4$6lyON3C z%b38R$nH#7T}Z+0!Z%DWs{C7+x98aQmuvWhSuk116SrdnAIHarp(Qi9k{wQS(%tWB zPm`=vVC1dwLqqQBK$4~kBiGSKYHjy7tbZ-KJ-g99lKWUGd-Cm}@MdMx;S2k2OL#*v zzOEYo-hQw|a}sWrfRcM|#eZFT_F(uQWS>p%P&;Smiscr~s^ndsJS2X#OeUNm$eSbt zcgO}VD@dKff>lSrta*85E-n=cj`S zPu9<$5ZN4&&9=}=%GP019Wucs9em|V-Uiv<_k`L=TO`muL+ISSPptmM(@oN^At}%_;WsfzScf>>o{b%w5$2b z`K*`;)dgA2VrhHx74Ec`X)A_}fr_XQfx`{6)8*NL+J56k9`>?1F!_X@u~sDth@A_i zRr{8NkdLH=QX5U&*-v9hS~%5z74&r?Y<8Q^_6=^dBZy&J_=M%%KghxQJ*281r4*D5 zCY$kbqn??pi?ar=7e7DBQ}7*IeipJbx=n3_rzZ9JR_YC~fc705P&A$mKiER;TlC+l zQOo!UDVZe~LfN)8J(xNwzGs}uK)SiJd4`LC)5ks42&WI=+XNG={Ni^0u^Apdc(FC? z*7jb|_)H6=1EF)~bpAnZQG-GdmJ$;@RNbGoJv5ug-KzRHFwC#qBu;a?tuBoL@G--2 z+rXi6XtX2^M#jz)g1IsqKe{9i$Q``*8 z=`l-Tr8wLRZAvL!Zhg{VZ>-c%6TIl&5e)QV0^iGa zK(!vA{N{|emdnN;rf}&gNRN0Zm|!AxT7*2eb?>D#<}klj%Rw_L_X*6gFoh#{-h1Wf zPu2zxqBrM;_dP$`bI#C?-8GkTF*M4JsUE8t9KLo5aqmM07@2V^7djY}GT?@aMLF1A4@~hxA0S2`MaR zdBTc@O?kLc*lNT-p2>j@+Bn&KY9iB zu%&L#mQ26lFpl@n+;HrGO$*CYA6brV8gNwo{SU&pNY!s|zASzq4pk$>F~4E!ZWmu< zs%(}otLNU7J}g~OzR8hLyxLl|lkkgY?^YPsXUvC;*5_?i)q}0fv(pkpEEnDtPQ}j^ zf()N>hY&1ffRp_QY7yqXyRfo78cW*nDnqKEOHQGpq3__DqaJ>s!(S(a^%C6*6bC!e*C7{ekgTn^5zDbkgF1K(%gznM(3M zhzVeH;FLKZ);*@xFjCHkjvCLsA4f{@-iz(%o#hM@ zpLn#905LF}`}*mX)UTV3!=zi5NAQ7+efn?wl?Pxc$U09JqGxoKTsdojr@&PP*z07x zocjyTu#9QX3v)x=?9Cd7#)I_Qa1D=&+!TcPLQ=Ker%t4(d;f-S4fiUl-qb+wsKo~> z)^G<}p4|*$IJ#XWjU|OQEH$CPN{1@D~ure3R(yH!)dUxuOAu+LP zF{j35gUIsmq|a4+s$(T3WX)38)e+^`(J#T_&S$yh6?=MfBFUNH8V7Ws#qwc&t z(JOl&*Dx0xLS|%(V|{mNW{%~Ot4o#DPp6D-{)66LezEnbfnX_M`=HSOUPQy$`Rp!E zD8!;kn!a-G7rBPiR@)fk|D)->1F8J~|NkSQlth%R>=ClJLuKzH`=IQ-_c~OPy~&m> z4%y=vm7RU8I7SGeWAAZZ->3KI_xr;i>U6r!HO}?C9{2nGb|=jxiUxccov!fUGLT$y z#n177)vNkGX|(s|6lfuN(bi{n9Ktv_Wrd7Rqjnl&3Qby5uH7H`MvA!+bVBWC@X zb8UW1D_IIu;2Yyc|bJ1P%Wf1xszZCKkhYc)qk;UATv_pyqKjC={A04z=-}T z#E;9#1?zy%#9oXow^=;T>u2q@Q0A%Dj`-s-t-B5hsE)*CKSu9v@258o;nOcxh@gKn z1H##H=aju`xiildHS@RFgq5fT`^0$zELR`_lT~E&v+mn^x&kFczPLxY-HI4e^`_<& zwwX^aC=sTw4&qcMr$0)(BJPhMTO$3nN4;{Cp9{-WVTTqnse0zv9}|JcCd!$uM+wFx zgF6QgsYpXl+&19B2`MeKh%luUr2T2kO!kShSfZB1N;L7Sc9BPJf-d!{JzJJag%mP8{R|}8;!VmKIF(M`V4g)IErgE1&}n3y*1KGUKN`H8+PY5UYE&%*8y6qod}=l`>u&&js7Tr&8Y;W>J1s$r)@nJ=;3^%dUF`*YRoRbMM@ zG-4K(DRqBtQ;s{_dZ3zQ&pTfomqxW};GIvpK&zU(%Jcbw#)G}e&3UJ~u7v!U$J=s? zaV>>MM$3-0j+Kk^5pk;~(1@RfW-Vuw^P#;pp>gPsTWlie2;*0K6a!vNMr!%O+a1qb z{89Ovc3un{+hm5`xjAZx`|QyH`V<~||Dtp3SsXiEA6rxjiQhCFJq=f_i<~Uh?VkOD zcd*y!Euqg(VZ6?X8`hAnHfd<>K6K-1v<;jH^7HK%iAHpeZbG#m6WqIgTjZiqG3@ehe{$ll>381fzO`8p9W2~u zposeveOZ2YrD_jvp=HS1&k?CAzb~kyA4_^(y>VEWCiLMj;vup;O4)RQ@}eZWHd(4_ zbP~yMuG;N0x9F!3*z0K3Vgniv68%`+xBvaqPB*6fn|rKqCH>EQhp-$zAzRszlA;R zy~^0E8@Z=ct;zF;`@~Sz@!3V2|M?XCTW-^!Noc?aOf0S*V{a5Pj=+pNb|CC{p zQ>#f~us>nrZpNj5OZ;KW*eEI6@_x(T2sTOmjxW-j@%=Tv< z?D*hjS?l_pade%Kx-OCxQ_Zr-l$$9Iw?r5fk8Y={zC!a>6eY~gcZm=0jjvgR8lsH7 zC*fBT(@x6@i}t!{J5<%vxD3V(_;4D{K8O`>^|c${ zRQyRluvp}vUTEvYz3rti=X;?i!A}n*9-Z2G_;ap(jo9Zmul^d<4%`G+#xwstFdh{F zY2R)Z;vw=Vq9IKADl^Sx0MQGKYgI%b-F)=0cZ-5`<}7lWdo_zZXBpagMveNS&&+3d zzlg#7ag-iidx$*d9VgUiF+6w4W$&|L#5|n>w~NwPJBA{TZ7EEWzj5cTe@01BSK^{V zP0-xIC_-Y#nJ=%pHer3fu5ZzY@nCdf^N;A~w^IBr1O383Dg$I`Pe0bs4fu1 z_cBN^z-2$hdtWPl#+=l}zCjACgW;GC>67&xvR?uE%Fr24lxxDxPYpHuAvSibw z&Hia-;5YV8yu+ie3`g&F<1d%P7?1vo>R9oU;zV<&GP;#2`Evi@bm28`3tQ&$FsZNf zBW;qZ4UwBTs*+XJyD^}H5b2}$d|W-u{Q1Xb{50x|L3acnx>kB6nmPjJO1p_=wx|Dct~LA2w;^K&XoZ+SnF#J1oKC^}P5 zFshlpINiq=ghBr;5!5Zfk>H7P2}qVcMcqan2F<)LCvVPc+4xkG4m|-1FP6)OiO&EK6{w6SlJB;BUlNTHQ4H= zkwJHmN#?z`1a6Ddo>5%}Xc1`3i}RoB*y3GNWrzdSzO1;9bK2rr2JNU7byGlI?;Vv$ zIp+FjYCIh}$%Gm~>{v?+2vbAo?$>M=PbB>O5@zUeZ6v?zTny~4z|0PbG+r%Uai9Ul zU{HV#$~}OyK4_C)9>N`h+#k170vs6FMD)?w#&o(F9b;!|Y7 zvYhAYv~K9UqXeKZ>>|+J`~go10B8WTOSY)+27*$0uNR#u|Lm@|JYXz|Kk{Ow1JE#X ziGutF%JbL>5dNVm$#TLeWGcu2m9P}VC|NlO6XPL8`Kh07tAeKoe2Qiv^T?ZQ97RA? zOulZVP^0XG?GGBZ+0D=bDG*PAgrfjti#-%bfc~H;q%Dg#LLvyu_7j&UJTPXiEz+ zpiygiM19|@4+|lU1K1ZK9p3Q(`oBH?R*<;{d!{H;mo?s6{Z-`fEDrRbh=M@7A~ zN#r>2U_5c_S;B5@=z74IQ0;y5iu9T{KIh$r37pOT>J~_$PSIFgUJe1WW?c!b58uKz zC(#fV^cl!M9^zHG7`-u$Gi%*Cdj&_o?dV4B7UG}qodlarB{yAE%p8`U;*K~7KM^hg z2_<)X+!uKLO*w<@$zkbd6x;N)3F>_qSyI9@FCk|P$_d0r0T(NG8%=srCU@3;^!T1F z_5T2D-*H_0${Bch1l<&wF+e)W8$Yf^kSMl9=k93Xe|x&fwU)-+fzI#G1JiE^)W6dE zU`PF_Q8=av3s^xJoWl=d>PCUqp*=*0giz0GMx>anU2!J6PvEf(QsazbLAwK>uMNrr zi3AllUs%NGpBTc(uwd9GIqq)v(s2fJT~mRlnpl@iZhQYB50G3yU>M@E+4JL z%R9;-Yed7TMY1Rikuk(yS-r?Fpr|C;MUw$FN?}$7IK%U!11E|M5!Z=o4zWA}qSZ?~ z&KcV0hlNW^Tvw+fg*H+weu2iLmT8`Wn15V-S2)ENvGL9K7UcUZUvIAo>XLO{Vv z5`vUIZ`joLxSDkar>*7ajX#J-6jk-XSk~)U^Gvn+iWeud4@gk|kNE`RNOwo^BQxX_ zRDlwtD5M3vLPFqt1dSHEb)As{ws{cP)vQYJK_dvKytx!+02eoFjCO5Hk}d9Gv30gA z9!0Ws{4z*UtR-g4-s{Gv0E#69bi&75#}ms_6orWb^(zZKO1KHRL!*XHXaLs;dO4oP z%|iCJa*_rMf*1`E0mgiSQlQnB6&APw@smKz!iyDO2(l6>D-SYpMB)^)_W;E2j;gYP zEuOuDLrJ6iSfTvK-Vuh)w~-JJl;k6q)?O)B&H|xkT3~Kx%U(lq=sA{BQOv@L!NCR! zYGNul>Ks7Z0!9LGSzU`>*B~h%=UB%ih%C0EU073php*WpvPpH1*Mz5P@hJ(5gAm;P18oOHx7 zweISF_C>6XeOTNf`wtR3S|9Ht?j)$=#IBQ`O`~4%Ep(~@u_R)4PSgyFCUURr|LlYs zUldu7>=?5gT}+yWGP}U{@Fw$>+K0zDq!*#+YHgnY5aSNbq%nQRR$O8=q5X9;roUYA z$D^OY#!(hK9h6BHUlxAtTs&PcJs5eRA0FYQd3HW>F&4L*XW9EhB5k(~cr8Q05d4ea zlC=J*5l{)R9l#ozBc)yDbXN2cRA@+;ovIvB;%Ie_G;wYGRE^$gMu9lpSuW8=rd$j6 zse_$`&e-zr#hZ`zHy@eVW}A~l2S$YI9w`4J`zvAd(b05LX56#v@$a1y*7b1FZT&iu ztUrn)`&H6+^|GuGJ39EIE|+p8FF-@PbxWi&|2~sGk(-~Jk67xOUXoqkh)NY$fKbwD z5vea>{wDtQt1MvdxKXedG}P90-2SqR4d1egIZI!HgpJ_#FLk)9aP8;0UXqD`)3Y#h z^ft7!n;Q|bA*-cx7Z-c?}6dPwtBL_Imx=Q~ci>59Pb7b+dG3T!qfpinYK5}U?&uqSq| zgy>0qH?eb+{ZLw$%y5D2MZA8(nLc~jsl6(#AFs>=+L4YuUSX$KID^mm5zdqsx^o8R zzLBaCxssLaGCj`~4@v@}U;(szbsamR`3YGSeqb7O`ohfR^8J0cg&UfH?X|G19gLkNuC?d4W>O|mqEL+9XqWx@NTq6@u=)*UTU*})P08X)J;5P& z=x&02?&1A3VDSg3V|U*q9kVw7^(`7i*el2P+dpuO#Ht@eX97u9< zr*1BP#PE2M?Rl<~YvJp#XhfJ5p-_fwrGFT5LUfG4Hgo%OY1I7dQ58vgiE;&uWn@v~ zzFVwAPW9wA50wB`$|7S@h6lCPfd8)_Xl}(J6X>U=-3{}`OCHlZJdOkP%L^!pv$ydp{8x75n8 zpB>VF)bcOPEw`Y|ZqKMQ9OwKwW@LlX5LNeTM`B6end4|184U!l?8T*?P+iQ1G9GU( zUg|>Jj;zOVG7mPngI9hSoBKp*!M<4%g@m51eRW#dcVS@j3d)`?+2jK80QEe*dfJAg zb!cd%Dtzp5qhbbTBq54i*7dvlLWoV9*TZgH&xQA8xBsrVHWt2}hQxGA?YKwhw!Zl^ z`k1oKXLDn0SwH? zY2OM&SET&0=G86zo56dPD6^@5&Yr!IM242GcyvoaTk&j}4I!*z2qPSKA;aK-6o zThX$$${w7{<_q4$Q|D)s>za4A6?JM(%1PDM=qP=yZ=>m4Vt;O5qE6Q{8{Y} z5?R=kEKe>7tlX6i1D(fF)>uF1eo@E1Z&$tm*!8!+#41%WIG~tBZ_4X^^%c5%P4HdT zsy8n8XBl_o9|l@&%GC+w6BrE8SLuhWd}|iW8svC;xmTU~{GaP1U)Hv;|rOG?i zlJ_!Po$K4&O)xbUSzBJOmW7?Yv@-rl!!BmYYRZr3!oJexGmVIRlKX=qU zuoVYB*^$+Z4JLkrnGkg41l=KRhe~QDr>#ehAgy`hwe6teSX;N1L)0|RdgS2C0?U-e zL|}3Ry@<#PYQOleQL?u_Ub?~M+;Y~@6Fa7pIEsjWnWwIo$5?minkNGjej!vGM9ZQUv zv#gA#`_sA2XXR~s((^4FqW3GRonKQhbx1v1p{l&a4I&r48+zxr2s~wgE*jSt5V%|& zmfbVIXp_wA{|V4HT~56@A8ydP$Xi^Nif`ZT;!Z~;HyNp-F z1(S!80lzLMl+CR)$c1FZzz%UczK8SYs*Ra*%h*{;a?Z$%m2oQY=HCb%5^LZzPCgLT zdC-FJ`gl?loxO2X$fdvPqLbliaG^BSyzkNjd{48HopYc^b>?%$074eua7y2l6(z+D;K@>*Gp#J zfDQu(*n+W5)QR4O{#EIHe}9^TzprY;%uFX2?5e@^JKTHbpIgpC*-NulVJ8iC&{z|< z^VcnB)@pKuj&K$&fy4QwUlo7Bt@A;gG`C^ zublOThRdhauc3TaSH?2+BM$GcTC1)E!QxJiVJ$`a)A}AWdxraimf~1uUP}F^^90WG zzNW^idQArl>Sb&9zq)Nj@8FUf@!fm$!&MUsTuMf8BNxR@ZECq#$+pFV8SvpuDq}H+ zM~eDShGoxsO(jXU;ClI0$Ne<&J;yx50SB>m-z#M^0{bfI>b-C@5v>0a0)Qe+1ERE_SzjSyR<5R6~Xw*$xHG~g@ znVTY_2653`(EB7UN!c@3v-h4UQXk%^Ns=sA$t5Ej-DGOYG>lZT`oIo*2GpdV>vV6; zswg^kqdjNG|ATx(g72cyt?bwhV1Uv40^Rw79^aWP(UhL6T*~SLNgx|ash-HrdTC-+ zj=O`yx=M^7!s5HtQmyWP_a0xqjOmR2MT~t{a8=}=`b^8lb}xfe8KN7~1^+=_2pb8| z3Y6w8N7K9jUbWB=p$FH_Hi~2|{LqpK&%9A0?WMW{wTKSth^v6#-T;za@)}z%Iag6d zB~JDH1>cg|ZlBY)Qj3pK_r;-pnx!QUv(awwwx+nJ_e7~#=*9lhE)+{Y*B^CS`+P5# zI!Y~VV1R62!vKr@&d9?S<9_mJuQj^;jpO=f$3N%#!Yr}FqLR>yxr~|Jf6>BXngs|} zq2jAC?&_A64{4{t>$nMoeJ@}G=&eVj$p2w5U22E;^>22a2Ta{YvLnMDcu&K8qWUdE zE=y9Q`PXBQ@;$lP;#=Tw=jWZdPY-);eLJa;W?swnp2PkDHO=~#siiUOJ8$kZ9r^a= z;nwTb$R{Q_nriR7nuuvkH~-qThkY!SE9lYVk!!zpC)Fi0V|*GeQzohKQx_cD^W%zE z;*!sa5>R4Jhr`)l7r^sGe=Oviez$Q~;A*PzPHy>wxeK)KD?|zV#o~IK?SKbCdr!(T zBUADs!vU_sB72cf_?dn)%)8o@TX@uGfaS~n>w=(D;}oI~{dBqxL2~sZ#@M^jnMI+p z0)$ZCdwF{DLw}}84m3Go;xC>s?+?Mp_>T+C&g~v;JQn7YRj<|Wwtdv^WhFT?vOZ+> zH{Ey(ke!>O&cPD_<&*O2KH_yUW{6UKr@Fl2);Kk$e&1-S^_nu+uI~cLMkwNs14>?d zGxCK#3UxI;sKzCC3v_QZ{eyCq2YhF>cyXbmTAEh9xO&+{MC?QGIQp)e-laj=u`jEx z_QeTNg&^vDkvk7V8oW0byWRMXgyb)lc+8^_r0W+jXxer>Vno=c z>*-*_)?eDA1R$=LpSs3jl^O}4ZQAc}TZ|hf8U-bol$c}5zW07rISHk79j)*EV@j#ZVB$hjj2U+p(3J*{fCGk=LEg zbYB%|9LVx?=W6)0f(^xF-S;cu=6LHP!AA+Feyo(ao$k?F_xkYCfwnU*s0Did7g~no zdr%fp0LVZ&?}N4Tjw(h-`Arla>Ycrd+bzwhmLmuFPL`oANmM%ciVWhbx3QhI^zpfU zjQl~DwZ1yPpD4~e)e?2Z>9TMqSBNiF8MBJ=dXuAkT*0HL{csdv&ByK7*UZ-x7=6z> zWiz-we~N<%>3*2zeJrXq+f&ArA5Fi(%%^j;h%gE_G2{JCpG>;QwB$;}4`#>T$8TT2 zoSd?+i1sTBx+7`&AyDrn0irsaoSY+}!z3bSot!a9!0BZBmc+Y_0X(C2&ZwWhhR?%c#-H#c_aTl++8 zp!2lg4C)|cYxEm@SR$Bk)QJv{h-RIlu^XKuR>B)8T zMCC`!!<1_quU2-{4=RKPq|2&#$8L}vRL@a;kZzNRWNE-lWzb7{Zv(@;pilH@4*Z^@ zKU$^Iwk%4d;cmR<9kpX2JyNn?`G&8!y;ZXgCG%T$z7M`0iJ2Y{j+Sg>L}gtltY74R zL@6;;ix05yJ&m~f`zhFK?DXqRr8LG~PVgikhpT^A5a0Om-=e1_jxo$rhV!iWAwb|DlM<(GT2)X(QhorGq`d0PP^h`ym6%Glt}f)XM))-tDs6+5MXHeCH7ig zl^~f$H)HN;ZaZ;FxWZYuSxN{rp&|gOqPq1yW%9-kWHp&cte^Bo`Dgh;=Pegtw@iO~ zHCF=IG(Ix*gBzbNUOWAoEnElZL>Jjp3AKVsqx*u4TDQ(+|cED9TC?x z9M{d!hw}f^e3{A*kJgq#=PRIo#X}e__05(Oo|Y4TS!Xl*%XLSc!|u4uAG63+aVodJ z6uJrb*E)=(ee`^sC;x`Jd|>nN4D-`f;v@Ewqw-)*R-x4xU#&g7gZ0z6#-j?=Y}t8D zVucu*FMfUpcL-0`8d~Kz)0AAERa^RwAhzHAg=)W)d7^4ikXkbUr|+0&Jm+^P*>m8V zX*o>BMa6Bw7t-PyNly^RZ;TnZ7L4r+=!ZC0a5Dk0Vyp-}WjPjp+g?huga}k!Ix}sf zGrJVAURy6MvsssYxRSp1_|Kas08;Lr;T=3r8*sd}VWRm_+2lUA>+l}pFY_h$r*S3Y z#D#(LzWhqF8v=1%o(!zK4K;jMB7j7Y7x~BC;p^Vp_lTPaZzFj(5UdFdJfSKh zO%n|!as{ZiNU-a6!J?(ncc6>Vx5xYcLK6JO3K$W>9oTuK?VjYj*Tr(c_dTxOa% zIKNg{gCAmatba!G`DTz&WXQ&$4b@H@-KT@GxxD+$-t2K z+~JYxS7S_GP3^4{h}&cha(s^h8g@5HX}q%1Mo}rN_XF*8F}838>6ydrXgB(DF<{WN z15kW9BLW^KNqKAk$T56nzVmhn^?0AOh=CVY-FY>YY{4+r*m0Q8NG8x84$WJ+fJqN_ zo_uU|JISQ1UH%Q@cu;AX5_ff!yJbj2z7C7f#|1n`upyz8Kk0#Z;(^%gLa1N~EybS}3%x)TNM#xCH`7(XZ$S@?Q+ zd;wTGlSfBGuX0;HM%G2)SQ6HhCiS0+G9r$mp+)YiCxMfrr||+ZBgYqXZQ^92~4pbqqY%z-W(J_V)bYeDTea z@g(=sJ~uqn_|*8K77Q(WO^f$*a_g8H7xqVUdxdm1#m!Raa1I`w#qtyRy7Tqva?F+E zJBE5wKBA6W4tG?mePp0vic>A~yt5;k3FfKK_{e@iFegFFul5qq1#aCU^2@EkJMKq| zapRctDb4U#^_S42ImF*)?ibwxsS#uyA=Ql0U^nRR=9im&a9MJU`>uqmFH+pje~n~X zjM!eFeIH?b5q_Xo3GX)!e#&zUcytY5hvwD4>AaZ)-5!f9`*RFGN4vbX?^$~n0G%y( zH-zA$>J?k9{S{fg+%SIwQL{J7VG3k)!FwYXrJmB8OI3l?`@$Ju{g&iW_sED26k z@B$jQ(dIyowFt=$8W!`R<~9zYtj1L>+1Z-k-6c*=9UD(;@D}a=*c?EMoh(B#^gtG-2Y#IJzm85qY3Vw6cMiMiMhZDki3xtdR);=nv+QKjfwY^ z_K?~qFW;>OHi&(xyA}iw(3zUQFg^iV{Ds+d)o+LDgE&dV_%+jg9nC{%FJIl)Uo8Y< zf1SAx7wyRkpEDg`7DxyyRRJN;8b0fisF#o%CB_rV7`fs*1D@O`BEXC?f)H}OaYo?} z2*}fV;@H3<(w+sc>=`GXWcTY*?}g!g@2ei7gHk057=Zhz%8LuOgizixhy?4{|JB@p z7#rY8OR@L2WNPwyJLVDoPmlz3Xi(OqDtpVe#7)!J(%?M`;oS=vzwuN{wy0=1o&<=F z;G?R_L!JzQnx|_F7(n{|L2D~ge7jvZ#0QjNFZFmj?FcSm@QHk5y3W_E+_mvXq?{r-xd>sX73k> z`bhP~g|)PpMeigEJQgcIlT+NQ*b;!R159l|*X3`CDb7kvb{c5hD-w8!qk&kH(4lvP zGGie4LWKfoLIBgfD8)-|E?@!@^DVPBWo6a+hVARKhXcgpLBffHpcGGo=@u?wX7dPX9v-kBjn0%H9_n3WUMfkj6`M7B*Pz&iq|w@&MJ9zm>v z!d%_ya>i0_UqsP&8q78Dhpe+T$e(HNtz?K!!5+BpS19_Y`dJCwg^r+GyF>zgtk{bxA#errrL4|R^ zo0Dp?y33irZg~6_@$ETcs>ohivme^Q6wt(e(*L!ldx@y&!U`%AuMn5Ru5|NX?5nm%Lkl z^Oh6ArEVP>w_MU>wv$ARwwa+vho2K7gd5q-)EY?%zL_B+LXqxq}H$AP!0>G*;wP)*bjgmm5?^(iBPiE zjkg?6?ZAlu;WVGn`a5t^CIGIP)VG*Yz}m!t)ocLN$ciwY^nmn4?~|EF&?LA85p#0% z7xRD1NR>=CKeO;*R2C}*eMYkI3&*+bR4@*7BGFIOL$nSe7LwQs@;`+;b74}-6?m+1 z6tig_Oe=Yy55;ONjV(#K%h zFY!I~`9H(V9dd+(ZMV?)1kq>W$+lwOx2i0^`Vy<0&Ip?~jb2DTS)Q0P{+B>{VT(A; zaBSzDd(YG1Jf4N%TB%jd@Q-rup8VdFqi6+&g|TgZWrtf$SoV9Hy*C*oChwxx!b^GX z{q-%LOct5xos!dFV6DMXHbIZapgm1ek)p6k{D~dKkN-MW3t@4Uomcj;Wy>To0m|mF zoT?IJClBbRnOowsC$_ntjQv1gb&uH3F;Gs-_&ilU?SuBzIPqpoMsb1lQ$WI*-dr$8 z%bogk(#CjxRaoTukMrW4R0^na@97vIcQ;gB>Q%@j0$;WVjyyANyBm zbGPqm@u&@C<7+p5{CQlVtDwPhbMJKWR*`S;PT$N(o0G|DLgnK`*1Ay9GLy^o96|UQ zTjtl4;YP&?^(l+?Ha==9{=v<1eM|JAzDtVJqj~2(=+7pTwW3GlRhRYtK>H{wwgqt~ z=xM97yY`&puzVD*|@vZoLy-)q@U9GY=4|Fb#rMYz96vPa`S=P zehK}cpHKt+h+-_qKkP9V`L7;5eE0`s#qA7LuZSBvJ$qTZz4dQ0n~kBK9+=4Y)z+8x zNp;GT*~OU^Lq0VN!dj(G%O2UEHN`N~8@eN5+8vV%9YezmqbF<4TdHeyL4VU7UHxgA z0OM73zA0NKktQW?Xh0o$!3M*&DCk0^T$MCF8NkZ!iiQ-mG#$`;i2fTXz!D!oGmHQ=h4f{taAGV9OFHt^b(>)9($^*V!h*ij*cAZx4Q>oPF)M zU+6VtuDWbIqvMiEc5I7Bnc(I+u42*f zNVjfR(#WVrO|pXA3T08`ek@u%c5>M}DM5I=4Ezr)VK|$w_0Z$NiSj(Bn)(kB+;f1N zI19gZFnszmZiI6D`GbG^MH%^(5GGN?c0BZL^I7Z5*f4#~I%=vBakIczBIlP48~f$T zy?*nGe>i59G6mWjit5EvW?Dj1M~*0+d)3E_YQ0;U-inL5vY_@qEcQ+5g1+v#^mIxA z$S-lafD9|-_ej_OAfl#ojKh^0`xLt2bF=SLW-*TO>*4U0V;oa{{!6cmntXk=jHAl= zA{T#;sA63GYlma*xYWM~3vO5H+)T4dW%vu}bL4heE@+ml8f?a8JfMc{ zk=c>H&6rT0(bG(cZA`hL&dB^En>v7DZdyWP4QgcHmsVbf+*PJ;4|%7U!ek zuLq*8b7PfQB<70Ud5-bSnhIA>P9wCsn*rwfz5hx^uhQby;e}(LiaZa^#eeT%O_I+m ztGU;Jjf&+-&=dSB_)UJ#n7nU-V z#lDgI`L5?Q9~ZIAh${8(ak4FoT3TX=tA-NBKKY#M5p((ww;t$KRplI;;9hB0J|h!5 zf=*RzJS4;ph~_*)#rI^MJo^_^t}OZMQ?cW$!FQM9+j{ia`u&yQ;Ozj;FFY0VwJk*x ztylb)U)Bn~kci84)5)0sdvh^Y2H!hzNRKtCq^(>udf&Flzv+2inMT(Vu&`ri{ByBm zWF&8R5*}Rt^S*9*MRj}7bHdtL#ZNc=1fyMjvtw#L(eAsxAW2xd+Q6IetfYl z+rjU6T=2Z*!-6ZimO%fmTmN!|CqbD-*SO#a9kR(e43D13V{r?ZOAQ95j=$^~K1=kA_xr%yPZ6cSO+% z9j`Q3c5zZbv4(YX*pEDxrhYn)tSX@#=8m_vgJdlz?rP?&N=x>R(!x5zD)OpuS78q7 zkBsd)NxdiGV7|vZVdYwitdV{f`VNe9=)C`fxR?DER3!Q1^t9b5jV@gz?1*Ku&3QIR z?tO!ssw+x%kpb?Crn8wQKu9>08M$XI><{VJjT(92HcASbOHQN5ZFZNdFC~hOl)Nj0-}G*6VT~BrTa=A%sy8cmge=8z z-SfrOt9ITk{~|XG^#_o%mPx08(qy~Sx90&$Jm}k|BAzVCD+P>ul?uuXdVB!YO_%6@ z}hV z7x1Me_KYQt{-wI?U)J!OlRC5L%;`Ztgr9pN0(Pp@0OP@5cabt4*2QhrS`aUReR|JM z2kprCB0bS2WdLOr!IE1gY@yL}{?CujViTlHv(Uj@+8}blAWYp^e0?yeQa(Dh%ou%(%SXgb2S22KkA#8xYd~5Znpv~^wYd@ z<^J-wB~y_GPf;CB6^n^UU_Sa>IQni@;5Wt}f;iy;!zX?!RSULrh(CfRd><|N4KSA- z!7z8kRs!s zV$ag_rK{V?pDdgc;Ft1nK119NMFdX!2tbEcYsv9FrZVrU)waT1F}I}8%Ya)Y!;Qz| zz@v8shM~}&I8FR5l3Q)y#GB1OD>W@%P?~zm>{?mq@9z(Ci62L!#A;EgJGp0nf*kI= zWOaGx+;ji;309ZyJ&zrIYJnF)9ja*7t?BBUzW}+!#WY!&JvkiSKJCKCVo?kF*_xM| zr_5NBFMqP#3^E|SN^BOmw^@>>GT3aXnUmT4>y8I@$V=w&3x)AQOcslr5Yp+&u z0h0Q(#R?6MvSOY+1 z;1_SG@aQ?s7rFUUU8E$Vy(UsE(~XJapA_83Ah2XxBLrY$S%8i354aN7T`qFZ`PDt! zAI~|Oi8G4$jo6M)pHC4cip&$v|ML93|4nz`_w&fQ^cj2a<3`KdyZVyBr$p%#3`YZ- z=bgd(XjVB|zO-I;7r4z-os==l*A_?bvlWj7EQ=*rPVXBwiXsVAy0-{P{1~=<7(7g% zAE^LiO$i!4WSR|~tm@dWH1B_>LF+7{h`CxC0=*2nsw5qpi>|juOqqKRi%36eE{SI| zk_1wsQcV2=2Z@d>K+&k;fc# zfj!<{{W6$Mr-PI5b9sFosRcRLGg^1l=x*<+QiU;-RV!^~)0Khl^X^O!-8M0&CUsPl zV6b!yr+|gGmnkn*-Fwm&_7iZcb;81jBXY4+(5*Vg^JgF*nC@fL(zrW3DERLS^w__1 zl;Wz5*4ev;u|G`bR4c!2rF2?oVq!taE`eHsa67A-u%_xr$;oMUVL>_Y+go9$mD&ec z7EQu@AH8TnqjR;=R?lzI9CX6sY%?ca?L%iJH)Y@XBO0X4B#Go>1t&j=3fa z%tfC6#k6G6+vx=CQVpTM*J~)!<+P9@q#Qvv61rGDvZ2Cw9~wq&%1B!^es$R6hvS-> z^6YnB*Ntv`N^}nzsZ6RiCG*yMp=a@M3bCSt*hHgkGSP79c%Da2otxqDyM(QB-d` zSg6>d$@qnBm^ooqvw3_uz;t-Y9i3{EVe)TrX+!;xOKIwBYXH(zGAec8w$@u$iDx^9 zM@Ul2p>__OOFBz%?he@%H}eaEdaC2bJ&wc8Z(fuI%M~HzxV?4g!NfWGLn6S6k)7J% zb;RLX$}Uqndg91`Ow$yL;x#{^YhpYYUt~lIb~?g#W&XX1+XU7t70jftr0?sqnfV;4 zH)gRG(j7EUCY&ycEGYcxqlUPHjm-yx2?|8q8wP2jq^_&k znMl)J9HPz~Jh_h{{=Uji;P2osTmD?%aJT|JBO7|PyJut4muYAE=B6c6iZc?aOR1PJJo)5gPb%_L4N9LLssub5MIn=F;Y<+|G&Nos-D4 zkImC!-RRFN4YJG!tE42aZ&VHXG z^@S>2tedB_XD|Z}DUXFRwzKPx`HkRs9R|&?1oSZ8GApp8WCH|FJXy})CD-L_fhqc7vq2r#sR@gZ#NRR zcV)HHB6P_Jp#d{gN(r$}(S>fIwdjW?1F}SW!9pjPp4r&9#0^u2pp+mIFK_fQVf>f^ z324B91G1Eg_u2)j48pUIt z4E{RtSbKh1qEyg?v6c@wW&~74z$^>HKIdynz7p za;nJeQlmvqJ?nRq{~+8uCwaF#RIcmT>#`6ekcVJ6TxT6k19~87+l};LNc9rQT2S34 zOEh#+=A$F1kw-9(8 z=p^IQEjfVe<5GUyv`^5Rh*NfIx7po39Fl)q7h=k3`&_pXmP+y;WD4xeq?Qsl(s*j) zlk6)laxefaxlOI_vZa0_5|S#A+qD?>Y{h3lSw$8M%ALd>TnZ&$3nZDR832SBDoeDG zNBj!R$!RnAH5mO<v|h;|!n z@jev*k|N}FJ*cUJNC^07bJI`Ejm1nrtidq^Ls6IlC}g?EfyV*v)|B8mFfJq3mT@63 z5oBw0lCHkUazM88Zr^g=5fnKOd;giYclf{6SDy8nV|)$oA7~SH;hL? zWb}r1qzW7iQ9%dKTFAp_ZBPfIEh_|GA06-3+MF61@H-bR&#;(gVk`q9Z z?Ycm-E*V^5JY2*o5ETu(#cn0=caea|sFe9=t#m^?j|lal80_imu`mxSFBr~(*)X1+ z00$@nB<2w6=#;%Jmwz2X1Mf~zFWp4j?yQf__I!uvYl3SL*sG9GK$=S|b=>6gZlr<& zl(sU`!;83+Asf{bO>|v7ACTVxsi5*hZDG&sr_dbe6e-dHL1OtIgz9{%^rB$n)eRaI z9c7U90TL8}2q^rxdHvsWj#aMRxmt;IQhl_j0OEwO*Pb+SAM_T!Z!b4lRQpgMwx@+n zqmYcJCEJ;}bR5)IKfB{6#vb*5d7V5MY&(xcU9|JWD7!UD_HX9B>wuP3KW*1`A}{qd z2E6j%$IZ&bE!61&060~W&(5C=fJZm=TkuW_+JJo`uZRw*MYsR(rjgZQd_9BNgd}u z1KO)W9WXAyICnUnZl1EyV<|{wUbNOYWyB72zmu2~U-x8Unp4`_z69u!is@Z6ueCi= zs%d=q#E8YpA{z-7Kr2!MAM#O)4>pb?N~jAOm1gdF(7g`Ozh(bk1f&eFk2m;Hfxtmq z6=;wI+sv^BeuZhClz~Xpo9mJO|Hl6Rr)F>}KqEs*@^c?Yxopow1?+N3KwLqc3Q%XF zz{z&&e*q;5Yw(ucV#%|Ven&$>|Bt5k4y5w^|HqFNDM?YvI7MWS?0KlHV;>~&th%lq^F{bSWRj{DsAbzjfNyod=@q>qKHX@I|w z^WvCrBLNqMAx+lmz6h`Eg>Y)#0T!!k1hpF6%M0t3#^A-v!7U|&Q<4kZ5Wy7!2RBIi z+6$FtHBPr?$cAJAtpTbMt|W1Tf5^d*f&*;~_XL+J6?ie6LAPQ!(Potp>jV!#pk9*U z$On0-xq}MVrUCiFCGx{m7kwM+072eCl*+CsAz|wAr;KqR~(gJ^*hoo@yLAc-ePjEQ0E*BUQ#vP z-50z0Jr}fn8I+V(xj5Z;8p)*(ZCzAZps~_@Vn~+7%GGRs?47VPjxyD^D+wg7vOK6k z@sA|gIDnz*X4I_HDCT*9LMemZ;vJ?!Mz^%s)FdW z5;M-^Zz>LSXr-B2EZNd^(6${}<#q?8hf?ZtRyi*7@^{U8NkUIp-R)=zv!oq0MLSYN0emP#y7=4Xx@#}_fxbOaQRI1 zFWJG@jVkMO$j9I+>_VNWuVQVa+-megWoqMV;e;@%{~#i_UOM}Kaye9{{gp8$<>kTA z7H@4)E6I`|`s?|)s|np==#st(BlCOecbseNcXkcg z)$1}dS$Zp0lND;Q-}PJW_?fS%Wv!WUaAs_eLB$(HvcS1i8E@VEf-lt zlE@IK;Oc)q)2gBc(np4?xE;rNAH`9^oXHO1`(y)$g$RQBqYqKoKVBV=)v^w5VS0GG zDr?m&C!b#rbW~x$wamW=mmh9Il&b!7In!uac3JJRoiDewDK(=P{N^#gu*mM;?N#I(gXcNtsQI>1W@c_n$Fu zPtS;mFnbhQw&e#JG-08CDdnpoo$}SGH&tBv|Nb;QzFRI)n9 z89bHKG!s~~f1{E*wfU!0D1g>?VmO;Pb(tfc^eN*_@tfP$VNBoBiovyHw!d&h+VxN>q#^Y&qiu2Mc}efoIzW{L?FF z;fRq~$xr?JpIoLT`>}^yo>sQuup73Xu8NC_HR9S7Lh>t6Tp1uf)ialxI(|h2e1)zW zZO#1pa#QoYy9|xi|{+X?rpi%rUPJOFm z^!Z9ROdx>K;Qb3ucd6FY4BCCC$ohy)B|LY|8$9yvTh-HzEe3eNk`h_j!cvv2UZKg9 zNtWUx)#8qjF+c;VN}l-*>v^a9lRuzhl1qu4?E<)(^b)IbKyqRP{k4Et+Eq=X%i}`> zIiZ4W@L!)lz$C~*C`;vvR5~7*PAUI=1msj_=|cZOo=g5Q6nCvTZu;BnE-hcdP-$OL zBqKf@6MNd!3XWW9t%k6j$oa6-=|NyqoM&qvs*0`Li^Yd|e%P0Fe-L`}Nrk;%Ott@6 zy4H$qaoW8rHw)p5iK=r?i7U|E{>hjM_E*z9bjRepv<>rNs3Dj(=CwDF`n7k$eAs{i zAh@`|>QVL5a+q}-OV-Q5Y9?8_(SkLq75`_Nt&@GhAuE^sJnT=#q!z2(>%=k0tJknX z$Kn4Vo|l*mgoL|G7`H3SGt_OvKdd=qvjl?&bRPsD;D;-}PI#a=E4yaj>SIsIIzo=2G_<@9Ueyo++rO z-sbYLQ5%5CT1`{KL@sh4s*kRih9~T>=~pwW&*R4s`05pmH~u`0H>c80PVvf&^eu9d zC7&>($IJOndXM>y+7~^Wr^iPyIW&iA#J}sna|rFLd*zT-c)k1PUtgbhLsP>dny>70 zO}w+hgE)k?4{PrIOYe($${CAJ<1wo-Pe@&k^r5U$nhm;jCSfWemXL2NG9&*cF5RZ3 z-`pJT5Vsev^+HfT;B|NxMSgFd;>XZ z?C#`2UVm0nDk2T7Yl$EolPFxH4d8KncIEB{lO)rVo9mAUL|+4W)_vsCWXYl0`~(o7 znZMvacyBkWXvf)V zoBDCYm}JA*2zK^o+f3K4dzAKKuMI8rtyhWg-D#5ZSt8;2M=eeAE9o-7zgXVO&N#8M z3Up7h5e-AL^1xPkv0ICt_Idpn0}gL~rx?j==HMkI=ot z0?}|?(M1ow;ti@_^3wAo+Ig6p!`endJJ0I(Lq|~WgP$wh>Ko~GA3IRdNtqJ(v6OO# z@6XH9%lbRjWOy>pPKfYtrCsB4T!{4-r^OE@q?UlZ%p|W+lU{E^(_#F(^w<6SC0A%* zr+30TdNN-~X{R4)pUM-fA`1x}&MRetzX}^t0{&#M#_8br9Hu+f=qLT=f-q5d*YF@_ z)`p!9)vJtoKQmFEx33O?ZIiUvRXj2zEgZX)^Ps}fmRvjfASol1fHr{DA*9FYya|tf^>V%Nf2AyX`{=<+UL@nVM z5kh@2Kr`m#T`lqj^G7I%nckxLw~3jo1XZldWG=Y_q|0`CivdRtHFJqd_eg*+hk`$~ zDRs5-{}g8exWYU2ds%O_cMv+HXj6nCp67 zZXh&)ZQu|~V1)iPn8du5eJSWR7)L>b1_aYRQJoB@?5PX75f5THt|-y3K@?Sy!y%wd z56m`*`NfMT1iu34PPjVmWL(1G2Hyb)K|`-h6;$hyqCpxw@bG{D|6VYJLmM?aWVUr& z6hI?5=(;mS!#%lk7{JUCAD-v92Dt=7Cn1qQz4Sl1PNvbnqSYi<6#OMe;OkscUC_XI zk2zUtW_2=&w)fwTDpH4b+Y${ideqzO>2=LT1C!VO^Bd4Ml0H%wU&`<=fvZ`IzGEr~ zLNVM24~0n4rB;{R|8>50JrbI>$q4syYy&V`Etd4j&K$i2`da5Xb zJGKEF`^#{UqyibZ$L>J?a!}z)u$orx07OLV9vE|5Ui05CXw8eO_kbt_Zj#0Vlt};; za#7q)&Xn{n&Q?T`Gw3E%Om#(k%iv^)`?6>d42|ZR_W%(sT2J}ag3q2oXp`PjkmIg` znS~38bKu-+85HEG8w1H+s1)!Qkl|<#@-bIxs|QG2QiJ`VvDvBl+Z@CkJk)w<>)@)4>LjCf?=wB2)UZqs~F zCDSA0^~E`YebQy{^B&QkvmsF3Uq2se=5u^$zv(nCmZy+ul8!w4BxX|GtGFJ#l)|3O!XeBp?4zF_x_L z|DXf_oI$c;l8nI^R}1p*>9eAP6{wM1Ab{jS#N+U~93Sk6uQB8@K}`WfcIaG`3txoMi_5ErldpZmu}pPiQUKMDw!4jF z*lgF$`S6%`r$dx2w51*Lzey9)o9semZGA+qZqGzz8Tx(z#mcn5C*Im z7Pqzp>5%+GgCTs*Ykg07w=R|sZew-&qiM4O27<|%MkIuzH)74-)+awilyNjxw6jy^ zT+-MFdZBZ~p^m#paCUBBvlYFsMpeCAh? zk$3qVa{dOsl_Aoxk}wdXu~@nx$d`QEVEgu1-m-qtkcXM{%=4m27*#U`GHu59wqVjP7158y0ZM6BR_0gh`HzYkX(+zn#hB`K1CLwxs%uFUT72J0Ky2DPBZ%*)+iU#%|7xL3|)$><{ z`ymFi;@H4_zBfp_ToeA_IEzoJQrA!)-dU7o?a<7bNvnI}5eBAIW6a{bIaOu{w6$&x zF4&kET*I{4rtI%C5!Lp0KTbQ7j-K`_CL5QT+`vt-mzTo%f^Kz5cG~qRUae0UPBL^l z^bHh~3y-P~K(D30s1&-V3>1=OCe=+GASqDEoj1(C+hFdm-LGKcWb$*DuYE}EcLK1G z1KKXpkk@O*`&-#`Xv0s+ery*)$L{Wu61_I8^y`W#HPJ^r^D+`|k~%sJvZ%S0Oe(+E zGzP?XH?OzkJW6G#@#igexca@_8*rI#i%eIfF_nJHmB(&j*&)PdRKIhIx^rxA6xfu! z(9BLvNy=O7UTV+?i)MG=@-4asG}rpg8wAA!-{+=4T@hgUKwray(0T0|60{7X zo(w@=P+b2BD~Uj4TGMcnkohK~1nNpe)#woxHapac=1k!)kj@KmA0stBh9ddOw*_AwAQeJQ4>>#p_A2u}QjxSwWy$e;e0 zjL@r@l#h+2g2Ro4Z2s3d94%LJSep~|xO#E!i?H#PTi`}I`M)G3aMK1oCqPjxdV$}8 z+sbXx3tch-L>7S5t|X}pi#%*~^qMZc3Ahoc(g#`x$L*+BW1($*XxNbbX9*`5vK>%)mR=s`1a=@%gk6!{B!MXg|SgLO}dvLo&ZNr~BW};&9@W73&@?qLIE76L=_lu&P9QlRkEf`{|q0 z9)-?1G%6mX>JE7(Dcoawi}cO`n?5bN`hXG3y*wYyGu5_rg^&-{eIvO;sYb}k5DtDB zdIwR^`1EHG4RN5a!OQ{Kz7WWaMhgRiDk~T+tN}v3^uQj5AE2BN(O5(y}mVyBwGzp?(!! z4X5Y@oQvlHaTfvf-w+yjjPyCk9LmpU%(xuhUUG;*ogS-NM>U7{k3P}GA<9YI0NK@2 z!7^M}?=>4BDZ1D28qv&kNEdccn8}26Xy!>nR+7lZs0mKn@8~QHhlW?(0qmIx`s8^m z&-qL{id~;8!}`mJfFYB~ZvWBnO><3gFAaAK_*YJ9*+7=irbF-j5J-8YHynpMwI4&;Pf2U3R;0@s(j$MOrG1_u1+CW6flo*e_Kz<<4uwD>N z66CQL0yLXn*20iG$P@rBWjrSj^lc3zEP`&mOLEJ8IQ@V5eIVToana+1egZ5)7d?tK z^pLN4PBMTlbJGNzX^d#44v8X1z9@+Tq=S>&1++xoe^n_k8xTL2ROlm~5mi z#7KOT30bd&8@6=nfnPSSUsa&V0Q*vMwBlht2K;|+O>i+-q@m5KhdT*|M=PXNjCpib z)k7D1NjSuq>ta?^Qz8wzg@yyxS{N=|2V67EAgJ9UA>_DDw-QU(%eXXzO`n~Mu>->w zFg$?aF<9la(jsgCl(%JA9u3#UQbhGpB{+yF2)%p~`F&u=nG3pLK7jco zf~$icBAymn&yR}^>TugupjDy%;JKfRu#OMD#9g`JU#Uk@xyGGG4`D{=wa{q7e1op0 zR(=J$X~2#r(SS)+SBneTFhHUxdNg7pQ}AAg^e&aCUg`&kyoA2l@5VyDEnC2v0a8vA z5O+ytU0a)Az*jUTkwHGPAwlvu@rf#8J?`Yg!HG=5tHeciln?3KZd6n3kX6-(Z)Q*t z_ay~SpG|tR1>HQV29tLXAot$i72eg2QJ{`Z@3?qG0VFmj9t0qYP($F(;0buEzZ7Ip zNM>*05GkPjYYB}?_~&$(aS0LpZ|g88gRB}X_j$_oDFTa7V~7GEkGTKwd?Ns_*bOxI zPYKX$g}w&X#tW8FXBJpvrNMzG4F*qsmQUKi<~KC^ocjSb-CARf*e7aUUJipfPM0e}L|Uf?0TV0PgbBbUFq zcK|Z>i1_zppk;ge-!xM?v4(cVuHWrNI6KAQ10>UxMbt*sGQ>X{$a!wNs)kO|ttp!+#JxIF0<`V}e#%w9r}7S8gE{mp`p0 zS~2I_fS9R<&3Oa>WKYv0@XEte0n{Pr(Cn-Wt0QcmBHrwRGA3&W`g%>q42ySWUT=x} zUAS5jGp~2@=Uu0@IVYr#{DHOQ{_%g1Df4r312Oxfe1_2lP+=zqfHfscbS@VlJMc7kN<-8vFDx~FH?sPaVCaXE4W``PG#vov$a&-0GO%!yFfjtcQRy7_1hS5 ze-~jcU#a6pkDe^n(Ga^Cx;Z?i>B##3g9I%f50_;&agRE^YPb~zOJF5*vG_$)^<2)G zY4+-^mmM7gh1ObK=dNVOqZE2<4_{@jYn1X6hI*`jQhpoI^MA$PFkoCLZ?!8DJm%o4 zkfeKv^}}gqHfm+JF`E2o^e)l9VfSeDGpWL-O<^g*P{c^gtR*q=Nbk%UlLQPXb-!V- z{~-F3`}An; z0{aF<5C@}&c^&T+rT%2->0BKxL+Ug%eWe-qy;6}FE%zzQ__^xZeyTA)=dh`?X!2Jc zp1&qLrPSLx64(%H2CG9hn?KLO9gx0@n{6NBS0le|bsZTp^Ljm{M6K#wJem6EwA+E>EQ^k%J$?^U)JHwXbi|9upZDLbAk^>C6H?Bh9y1 zX8LL*lilgCg>P*~ii@Ko7qv80_ZF(u?VPwJJln)#;bcc6gJM^PnCPm=oy{YLw|pw;SZXnO1qi2wD9{~#;MjUZ6H zO#3kC>^tvoOjokRxhLwJ3Y_)hDlgt;Q=DGgPIiuzb(TTz9yR?tw;K=zd4xCSiL20~ z9npmLj|WXINPEQ2uFKTiu(BjMFd$|D`k2ssGWa%%b4y^ zAjb3e8WnUplsAv+he;S0u;yI~CpSpw4;7DibzJ8=lInP%P9wF&hOcoTlZ|lZ?JsrQ z5?B&3g@J!ElA6l5td1N##4!Ws- z2;63D^KaWPOpp*UBQSlApJ9)R8OozC<-L2t`k8+(%lflW0a1X$6ZL9nlizC!|D)=X z8QQvVMJc*Pd?vvOig|eid@T~UZ&7_>*Tc$g5#6I}HFF$6M{i9)RF{Rxz>i+NFTP8lZ=QCGn^~{zc3sN6HoMte(CRBTNGU(2)EfxPT^cOrV zEHB#`2s`@ew}_*fGrKL&Kf}r7| zDy+~2W-`2`0ZhxTc<4;xwTm57+- z6X#7Gn++q8&bkc?5sY^iDjT&HOQZZ(`{pS7rMkpM?69trNSx`@(+4^!`)e&;d335v z0%u|z4JJf_?R4)Q!Vq}YRV-lX0c3-M9v-KLVtp2PW!8J0zP-wM-Pl_urVO(xC zPXC(&4f_vrZX04wy|(hBxY z5oPS?lKnRc0LE>kK?z(60~vp~Loj-A0MrHC{^ICAw~X zBI(N}V`CvKQl&NaPp#%9XBE4Q)s1M<0^QB@YzVmoXISks79-PaUUss#w3q5?8#I}? z@ixt2%M3kJaO*TRlOw#`&$Di#hemQ3_ydhHlV%pGQ}<%fmQ6&KFSB31v4gbYu763A0~s~9GLWTVF2=}8Ldf1+;X=*EM3!g$GyTgJH>UGA1}>pB8OOO?Nv~j^kB-j1P?mBneJ<#@ zhfLaR{|A-dgm22Sd|ur&_3N&O!UO6Voa)n%z0t{UeDaO)YgD%uw)G!;G}^(+z6stm zrTNXqZKY(tX+gp~=7s57eRHGi*g1#v2I;EUd zxP!OL9dPHYdG5I2iBG$Jzn|rh?76)96K*vIulql`dQZ?>?%mWjYrpbr9;SYUo-h^+ zBXiUXO*>vY{@!J2JMupSF)89bx^GvT7iXndoYIf2Yl}{6F=TvU%RDcxKK1UK z#&UW4^3)uf4&ZIP%o6#n(RK2d&`4=8p$6u^ywCZ5n@%S4MET2@R`k!G>;|h#uWEj* zsK7S_9dAre9dBd_cgjE6409+Xvbx+#Z8U1K=HHd-%FC;AJ*h79^57ekYZH}A2$K2% z&SmDf@Sm6=>wtO_r*q#{mApe_UGArfcKOya;fFB67}lB6+prSX?^8ZnPz(8?!TGB& zHs0@pERKJ?UO$}(n`PHsA9{Ux+*4!Dku7@K3;k?@ja9`Mo4cBDyHBAP=?rz5FFYuh54js>?9Qf^ zhYx-lE_Ijg3%Wr_!cAPof9#=__dNWQV)&5n(c?u9@A(efrepMiTXNsjkQDriO_(5qD>4Tp~(_ zi!c*uYkpPnrb$oD_tR!CZ@GTUP5r8HyTkmUeeAvx* z&dXK*P#eE&F+}v2A5G!`6Hs6GSL*}(Z}8@#dLO3u%Th_SmXmHNhAAS}q{FMC`=U5s^C@uLg!+ve z&@^STfoMecW&8KE%lcL!Q$C^F?&h5Ad=65bk63Ba@}&B!EL_gSR+0jGQ&;KEQ$*1X zm)?8o(4r33W5)hG9iFjLyZtlILZ#Ac8Ir{EH3#>I?uwB4w!wLG$fDhS5B_#t$2*tV zu6rLA_zSq?JC9A1quF$xCh3)t$jw;DFJUDcx~9_g&d6OMM&nx zF$U$lPwm%;_9jc?7XQLq(a$1Ibhj5PDjmn99(`a?*@{iA?VL|Z(}X=Kk61He4Zt8C zDeMY)cggW!w%!iE9aCzk4T6W>8ttD+N6xcO@82H~JR>CEER{^58%LQBjJ@%5qxn!= zc8R*I=&b17YVcdR^)HdSG%k(tf?wbLri;Nh{X!aZ2pBx^%AT1pZop+7dw28RdzdC| zpv$nb_^Ng&8#`XIOkp_jeRIRt^4Rcpp|R4{f<=){??aZOhv^xayj@?DbF70*7K@x$ z6B6hyzpPAC{ilqOjo_IM&*R_NDi@(aYxlej@Jm`tcwOlx-HOpQidfk_ z;ze^7|IR<%V+p`ikD;EL%Gh!y*F_JGxX|SxCF;?u$guY{^jQ zo2%;ktD8?NZwzBt8cOS<8249)&^~1~=7}*-Q&7|C^_K@3@2bRf)-3w|nsld@(6bX% zTAb0D3T4`>FEtC{t^OV-f{U8DdIpk4_ub7C15ohK46DXyl+9|z(}?B<1Lh{*YFIru z#>2%{<+VJgTI%#&hff%YvCp+1M{rHrj+9g;JUUjZbfoEVpH(BqO|4GKddAza{A%Cq z3w-+OSGqp2GH7?_=I+1cRaM=DZPfmHeQiUl!1%+C^%{Ea^p_fRw_ ze)9hD9Jn}o6y#9j>zcL?e70!#&4%4ilkdQ_K}U$p<*wh^VSjCTP1H(X(<$CmyZ?~H zcc+(Du|)N8MZie^P>D(^SnGprwVy!NHT>c0@{&Wh2pZ+dz>sMBgzl>;FB=kP zRZgG9jWa76m^aj%3~72A`f7&#)GTI-E6-kb+r1U`CJN6#T6@P~;ln}QBgbxvnyH4c zk>^g2rA-l8BGuy~sTG4hVxue5P;7L6Z-erBdUNHba6uIrgO{JQLZlFEC?@6wi-gS>^Ks0F8L|voG662en8vGtI z7iOq#IXmQHcMxjSxur0Xo&a>%Hop3qv(ExHaFuouxwHq0{j};X%pbVLhGvdTpOBY# zIQNzrRZ~gX`^7W-mgHGv+9rF;9p)gw{o`5-alb0>$k(q%b~KS~y=_@mz-CU8xn<^f&JzrnOzm6v@E3gc`<{8p;h^(m;PZC+iu|(7pLcHa z@iCBa5KUb=eMc>I?$^+hs2lR{^{js)A29BD-~*H1n~#|ej#Cy-vY||>J2Crr`-y|l zL|VR|9!Gf{_7fnnUL1$b1G^UYL`Z&tI>Ld;R$AeLpyvm){FTm0IB;cLeEC23%S9|S zZRB}we*ZKEAiA+M!?76y5G4+7jsieXBv5W6=zumm=Fp~dO^?Z5prJ4Y`U0?0FA=+H zF$yFdBwkLZ9kEuH`&q&14JDBn2$xLYYkM*ASeoAI9Cx$&I*TASY9Cu6@$)EX%)e5S8UzMnAaq}vedER@2)O{QcGJ3J3wNbcpkXih zU#L|t^H4QlSUDh!$N8ZC$CLr^PZ#j_H3jiowhr_j5rKWI=9A|yeuj6lDnCH6eAr8na=MESM zZ}Q|3*6s-aHlq%Y5rT1b+NMF2p%80b&-{@c%uQEw>U%plL^jMV|YEReEv zfrx{H8^>U>nBO5OJ_$i&8h@ETLQ2Hv0KY^K4JWcCE`#h+oN&DzKLr-y$TK5Y0?}mS zDP1%UNqcRbzk8vQOU$6i(*vd?LHbw=;5f-d<1B)~8?&hS2;lA%IZM&8dJxgXJZ3%B z9H5@l1?4e7B?O!*cy;x6)!-BW)B@m{|DTGA3&RLBa_<0Ng1jiI0zW6sm>QOs&{G1q zI(?-sU?MvhL_yYb>oA=}0p z*G?9(M~(r_ZLE~D=-tWf8^pm%(sKAa_ty$?ft$`xWK?iP8<_#Qa`Jyq#xlLVDF*3K zlduw>x%0Jce>vyKY=`M=OK1t*QE-abXy63EV9ZQ_pHu8Q1IG^<*>K`S{_YcUFIHL^ z_iosFX6c)DP}7RXnlv3K6zn-5_d4AtmXyzR_D)87jvVEz%{P^s+;>}K^dHH`KHLgV z8Tk;`v5{%1%$ufKLU3vu9W^!~v~MpdlQ{djb-156re8~RD1!!43QU0*4(;n4?Kj62 zZ_<7xUB)L}PwYXjpE1hYMIKVPw2W?l6tf!o2JJN`{H&2&z*#=_#zOIasMRmUHM28k z&zE;fW1bCe`73%{!&u7Fbq-Rr*9T9DtnivY8N_Ra5{DMl*}Yz%z7~2}7&D)beVFE# z*>sr_ey!Ol9tj=A`g5J`S^Ni?7Bg=*CNwtaP4EiWx_8P51gx1;7MMYoi2Iz;(G(?p z5{9koV42w`fY^Ec(RxkC8SUY-QBPpe|hT%MW4?- zO-#g+CFRY7p#mFfxZR!5|3Vn8n)~c8z;89QOJq88P+1Rm94(JgC#y|&JWefm#iiCw zpAXQmaICBvpM z!#SItjCn$CzN6?= zWIi{4GSZ)sWp^|LodB_0;Pecjp4~CShF>QB{z$AVMQz8J>YNTQ4&2t$)}ZW%>YBwD zXYToojj|JAxSCBtsEu}hX_ub)QOwWZZ$o#EJ)8G-1c~o$6IwqU zgjh$%hv^6_IoZ59EZ8r;&g=EKwJ)q5^~a2dad7YmfDY|wPe2FowE*DQ+b|u>AbxYe zF&)a$x!JsS>JFR;ajo*G&$yDkhnu(e%IX5Drh7r*@3rO)3F2ENXJ2LGb*Cz?4_?R* zV@F?zMM+=Jlwj}w9d(Ygn{S0ZJD3N*HD6^)8)H@;*05UTwuiaTvL7Me#&$Yavl?V( zdrE8qfYkiR1k%UO(0cv>D~hmg`r+4y(XINxUD#-mcj%dlomFN@;Ni~l@!j3a@@F&q z6a7S4yP=IH6QRvB4O;m%3ZIl;w~U(Ci%=`dNk__^N{4Sx$1+#Go|1h#R0eCw-o4}O z^%oyZULFm%M`U8gM6%HtZ!(!&lTVrMcD#Diy&nBF{J%Nw|kh?p^UkYr6aju#nd zko8*SY8pu{^tN6)Agbq=-lJa5N$g+Y)mAtb{et(sFMnQiQ*VdiygJ+Cs-DC1MIOq8 zs1CZo6~d?gAhS0bpuTH8#8aogr5_*T(zV}NL?n)Tj)TsHNQSQma!wH6)x zIWob6XMnb+8cpu;g041%Fw<+L*?twv!mF)UHdIBMx`_2*a2EEcJd|7suzTCXZ$9K? zfcvA)=485y-43L$zEmo-YKZPSzcv5OW;}9Hf2q3WMuUT|i zCh4xq8R~KK-Uw=sXT$&b6Qs!b&Ho_E{4SFcz4<@DnSQITpMLq2RU5nw&-6w$IR2*a zMt;Rn>!l9IUL70~6WmyTpQ!hH+$|zbzP6;P_-|p$Am7uN1VTORqiughMcO|Xh6YXc zn|O?efp0)a0;xb5OJ=mP%$3E+6>fe?yObbh;->wIg?@A7p~hO*^4{5crtWMtY|VYA zf5!?1$2vei9!6I1M{N8Dq2MfKy3-^eiBkYs5>bJLBON!q44vl5>NSr&fpzaQ+1Gun zf{TugNQVn+Jr=EWIyxe3nwf`*qpa!*&pPHFfF$lR)6pPGyoAS!@ct{a+n*E8NtF)) z?-Xf`_U(=(-V71rsGU4*O2=ixe2XUqRu9g3-VD>>?f3yTrFO7&>|p9f+;kbGv|8z@ zeDp<8j<<4Dk=T-2eZH=C5m2I5%86Ss){5wEc9axzGPe2b_j~i~3E7lQg%8crYgci% z`lZbe-{iiO*D70IrS;t~>=2SQxpgI@-6gaIn)<{oJJl?HyZ?iCCr3)zmT#~c%-vJU z#_G8lOYNjv#7KeQC&$-VKMyp4{q?Iu#`3K{|1<$K@Ls<<{?s7~6r;6%-!5Urd3{KP zI?B5*xb>3p#?+$|fC=-he;n$u0Xf58Lkp zFUv#p`xypT?~2@0Z+txP6&^yKOKiMG_GS+=xL0#)Y|~Ja+v)*J>2;9XrIc^$sxH%U zx5bk283&p8VAr%k$Bp4woOI6h#s-wNeP@m()t`Xb?adbfu5dHenZ3b_x|qIXrs|kW zTkV$I`-g|6msUScg5cuPFp$!wkMba^ZOk%%VXF1zJogp#PL=tUy%iMPoDNy-+#ZcL ze!y4qwr9zoQ1)wnzqmw1$Bw(LaItwkcV@H>Id)y-78rDD32JRE0b zzdDH;FTn{##<6q6q&Lu7ceqIB-hNi2Z)z`t5|FdY9Gp2PolR8UIP5yxeOOz}q8c(P zh+40wmiV-QkCyJGx`%^55}x$4+Sl<5uzO#lxBRnFsNHh4!*lYf)`>}Z>1{t&9XfoP zc9pBnxapci%#~-m@~&zuQkHNS75uFI)@bz9FSgL<3&Bw}9}XoMCRYzSf3&XK^Uw#G1Y^y-!-H&&dfUvfo`)@9Rlw3_mus;eimPIbXU$8St?HqL3I1z76k z$~F(Rk4A>=zV^YcNcObK4@sQ6JEqF--{9u7 z@D2(Yc?dQ&&@*>16u@xhI{~+*BNw=DgY;#evM`#k4A&Co z+$YS)l<7a*_KmT-SU33_{jdF^~%6a#jf(@lhNsP50;H+ zK4qsk#$EZv$wI^6NZ*z*xASZ^tOab3?x}mNUiAk8EnDAa0x@6;H9xUm-0Sh#Hh~pa z10)OK_TKh+eUXP&L6Ln5yzC~BwFI+WUZJjf>saOA-?i3O{rRFbx%E-83(yYL;vyCS zld7rWU~Q<#2ifJ}Q$x#KGn2loD;D&eu*FZUv%XuD!yftZ8I@AsZmMz)pN$ZR80pic zZ{9Big-m(<$3F)5d$NB&DDHKkHY0bM4G}yiA0be?(UhzUPMZY6E&*2^k2`1Tgi1T2 zvaV`$@wAlc%o3!^sfvN1*^=UEp;?Wu(7z01C;IB@yvfz)?T_k~DF&}l^p|q?=%B5~ zLd=%xsoHojs>f2Z!Fz?$wNop-hYdOF#FYbvp%pq~CC>31P!WigQ$MxO@yBJ;!%!-_ z{1MdKDKfCpw$g>KJz|c_`J8sAwH{mSu)hH-dA37eniTeT>-7CK7(w@(XE|id(`1l# zuaNb@OOMZ^FHqjns5%~QkIU|l{uS0Yy&S2ZJ)SoCIfA`rIBoqtTa~oh>>0L} zLmAkUu4fjKYH5dDEWXyMxx#$>NqN!HB_=I^$GjbF%t(Cr7#k(nL(ImKom)cn3>vtm z_3HnFfWhR13Wm#HAM(NBvA;|+8XjpKgHFW3*TmG zvbOL;cvrC6GX);TUp{-D4sXn~5wu0jStZtmk(wmHWdt4{`{dY-CWi2SA9< zqy8$1{B=tC`5&-@&zkZz$Zak$HU51tz`*4B&*yY7>0>Jo&2Z0%r%2#)=x9ZQVftn$ zi~xoKMKLa4*F-jhDU(G)n46iw=c0az1V;n@ya#7#fl+ zGk@dpK~wfLylW2w)j-DKHU>MoR|f=pTI7TY$!FZMobNXC+qRw9$Bwl8PW1dW;#F7$1#zcC!d-LA)Aw2~R+FYeaGU;*u&dYW;Qc*#$=u?z=w4JU z)4bG$_9mS5&d`#PMV)giOi0`tC_98B8c}hqd_4aqel^ZHjU=3Lx8=i682q^yJXB4b zdK>?PsP3BG`c{C6{)Bx4acMqJ_YiwG`;?HM*K??z-s_^{9b#bDTC(yk{bY%T?z@@< zJ>vF1(N$gtIgu34E^L)Yo%lD3-b#arl6oZhPQ-JtBpLttaa@%1cOGt{N)LG@o<&!wF+!1F%Dgob>4;#OolVL~1|TRkfr@so;0yTrxSHl|15z?1pf zt;durw*8@xus@iN7*Ko989vb%v?NX=B}NaOJKrJg!``O2-J1tM5DfUj%ctpU-dXU7 zkM<3>oOWjYO+m=#F@2-UdvNX>=)O%~cIqk!bd3M*(?2mmYpxjl-Hi1bYvmq%A!_hI z;(i(aTcd}eq0sn`h43;59c|rF@%hZXVklKLK5IIvC;iN|=qSnB;b~z7g_Ra18E8sD zJ^{!52CDUm>zFwo?$ho74En3i#N?|}<#=RDxM)B4o! zu(>$GibI@T`{#CXVf@rqxM#vt@9_SY$gRlT;~`mC-j4vE>gDt2%91k?ahY@Fx7JvS z!gt>6TA)f)X8pI*nVRO^`{Y*-i0;pD?XAn2vIe8^7GhS^`3hI(%cEAeO?QvNM-5eH zgZ@9R-a4+S_kSNBt%Mi@6+~2Wl+x`m=ywfa1KL9y=r(%8 zT77@=26@`McXeuZFdgFxoaG6O0$M@atHeP5*lp^R1mj0N_Oc^MOK0=osT6Y4xK-sH zUXStSID9nrds*d-3!Y#DM&%+8bs60LT*j&V#O?LhCQhvtF+~_tZsqQA2E|XUztgCA z@%Tsq$$tCWg4d*Y$n3=yC#4CL7Yt6oq08q23h&Qw%1hBiG!VUjOaWO~Fv}Q0~GQX_! z-Ugs0$BsTZCh~kRus{wIGWHOx2JyxKx5%ykZbwyOj#GAXI`-V9K?HX@QXx0)vX= zv|zlJ8VWd-w|VUV{Y8`1J$ck%3ZFL{D0!0dI1o4;FNJfW%G)H;M^#a1Z#MyJ6Nxx54Snp4u1oOO?|*f00AqRna|7Nw|BQl21eSKUp69#gw@+2;6jPuTneqD^2}5?Qh4HBvmz8NjyTVaX9r3RCy(+39EvFsTpgM>}#k0?BOs z$#8N$d3d8!omhUn$czw3%z?rFFu9qzK;)-HA``1c&>92ezxCen$LGf?jS<%&U?rRy zAQN;39am~_AEWtca%ne|8z!Z0$lDct7Io(Ek*k*N>9^TajK7jE4m>z^; zk{FH!izQCK=Cl#S*wf>1BM0f!Q%fniz0vy-G z8j)oi*tmK)GU{?Jx~n2~yI{%%;mW{{48EF( zDkudwTjzjq-J>CxPRF1W0?Y@qV*zsp9MGUSF1NF&=28`}0hS}1#MA&!El2?smD3OE z2_3-Wb;DHI+cdMNAi8Q$oDTVKaW0VHab0XKoKRRT=2=uWel_sc?HuUQHBq+W$Y;Qr ztX)Q=wOu1S=>pszoG~W|R*x3&P}T`(El08=RwqC=P(lCyue8D5|FN*Qs8Sd5Fy8}F>*W&*ZrSW+N|B9vZ-I-`bm#WQdwSy`_s7 z66Nj8c{a3H@Lp7Uw{^SJmQ^Q^pBH!;ojO|`D&q>Mf$f?m(6=dqv-LlH^*?bQX+;7G z4X~pmi$FGG*Tu<39ZkT3iX+(cj`0!?eB^YGIp&H|)F2JVHQB4x z)pR*)wo*lk$w^fbrV*<0;8us^(Hp)I61CVof^}I*wMyvTK2<4&DxWZFL^#0P&*glgR}Kf>2p5HH6^4R=!V}z;^XKy|@ zi99)aNa1)WqJ8A>GINW!SL{$`iTIlNFNE;5qWDxGV1#p$xpW?6aOjJNwv?bgQfk>N`m(neNO_WQx0 zdG=IEW8+%b#cB^Z-CWnHe#v=i2KVb?Zt&?G9ofd#t4`C8N~_ctZNfS&9^;z&Ta+E1 zFD(}IFy{|YO`3*jHwG}~Ayb|-l7Fq)Sp84iD$gB)3!PMdDt|#eld%_;pj_$4$dy`p zU(-gVruM!ezHUOwVD*W2(_e^xRF$|+i4(%CbY!<{(L(my5`cf-?G&@HO&L{%Cc1UE zm8-RP<+c5Hk*Gv)Oo6a$w;2g0c`TfM&7xojlk z`U?lzHN#oA#xDFRU=t1#>Ghbh7>WvW=3Z_ph97E4D;GZ*- z)e5igtv_-0imb5^*=;a_r?PnAHM**L1MB{iF%UNWk|swBG<1(jgSAep830P za~HHCf%D976F4qDN)$WtV!Oa;$jqna*{c4dxr3ijna+5oe~d$Y(=IGO zZLatWsc|AgV|-H$yeAK8Z+M+xfh$&VY@xbV;u?VrWcm8#u1E|iM2T8!%+ur;r(%*e zkQ=h$P7_aNOcqUMXAUUn`Uhb?@*H8%QjhY;RI zj8{0USr zo{e+HO}$9*@D^M9F1qH_%uc2c`75DaE%xrs2ct`;T+!>3f0iQp41lOw#Z50XF;^v# zw;?2VyEBd1_RHz&XO+^q8o2$ht8QC6_t!mZZ}KYZeMFq7tnf$^z1bo^-0z2&-ri+( zq#>mGd!!(K&<9#1jJl4uezZqzPK?Yj29I@a0WzzkXEMLJC1p9$en)C`5Ja2bPxP%Z zerSXrh>%}a*D+)BK?hl0)+Xo!1fKTy)M@9crBLl0@7MxHpR*h&4c*ib~3N^+%c z%$26H=IS?0TLA-kCPTvG6I-R5y*C+GH57Xogb2Ex2?gb^y5t!9J~d+NE7ID$t|P`?>JGWPeQWrdJ%K1l6wOh*Z58+M)%_>UF#6vyMn+TBzkH1j z<{U0|@i#qn566|U)BHm9o42+(9O@^kzf=0KaVuf|Ty8YC@VD5oFctx7R9Mx5SusDV z)V2Bky2sL{Q9@OTdLh>N4xfN+bgeuwze>~q-=)?O8mfGd#=bx3T(<3dKBsH{Bj)S{ z)AtE2myOGYOE%P}#g#F?eN(=vdn?yI7qWFra;0Z{uvZunV}m;1e&@Os;%reIw|w(P z=p0STuCHz{m$9q@A@xvz*qu`bA9N-o0P(q zYm{*(1#gZ@XtT*^_2D_f9gaS%WmanvV#n0*g(Or%&AunR>op#oC)su8u*s@Cj0i&yTalg}+^$#FXzv!R#p*KE=8^VMxi zlsZoF991asOkifjAfhLG_*9!sE1RW`N6XPWDW*T}w%E1>LQyh#-UW{&swjKhL&fxR zH~WpQuUiVPNi?JNN9INGjUAJplaFMc5(?uxujre@x4G*y0Ys?mF1k@yMp?GzQ+D#*Bge_u0lBcl z778XBz{tILF1usg%U_mXE=!B&RKC7#*%eJKe9z88+_AkBaf4?9_}T?WVvQ2YXAcFj zOAW6!QXY3QR=KsREu!9^_KdYsS4}lXEU68bPK(rDEpH^ISUw%{ZkFkAX8l<0CZhO0 ziujBNy->pGoqpB-&U`sy-CG>~%UGat;pMwOZX6r)CnLICx&5-v z+_l&l`l;#h(jE&=zD_dJ^Ww~y?3PTIMQkC@Ew=j2{Z9yPoN$#QH6Soa115SvdaS@) zqO|(f%6~8BvDuRY!5t;9+HzXwzUR>DVMNo0RQbb(=T4VJVT;_qmrgLJe9Tpf@Q^h7 ziX!Eg6-TNfMVC>&C-1})&mR%(H+5nRQM4&T&RSPznho|v&Da)`9y#eS-{J?$#9nvG zn8GU|1H>Vd;%h&#Y(BShd=c=%tuYv2Mt+gc)-Bk+GVuR}V80WeYl>y^vHIN6Znm5W zg`DtLaT{|`V)o1Q)jnTMR0$^poX(>3_;XugPgo|zK3pOQTlC)Y>Xerl7Wa&GY%OlQ z#$)#}*CmYSgk!qtz~U}`uPpzY{YZL@cc?fA)!R!;88RuoW7uEMxgvk~cn8k-eLZRP zJ5p|T>g{EJc==_AhV-=j>Y!ND{b)um)(pugkR;=`-tuzzc+3xTlxh2}XI7>EdME1O zFCZzEz#9q6{E?L%62NCii z-cMN0HP{U`@Xx+t=l1tP&pjxcY||-e@W!>^+drp^cF)%p#x_Oq?^LCa{1QJKasl$V z5Z`&swX&SHa-IVxGK-C<%tZN`3mx^~GA8Ob8Z8kvd4 za~GY@*sJ+gcl6L931f^jq!m8-Mm^VwtEkRAI^VzRu=HbdjHcP;@Y%I?4t|@rT}vmO z1EWHfj}VEPV@niiOCc2Xg^}OBnVHONttDZD0?L&q2Tew<{r;%Y9J9KvVp9K0Pob}9 z%7$KkRk`h5&(QZ)A41lp{@!8a@tAD!3c*K^^R8%;Y2732+31fYU}_;yoOg#!UFWJ0 z>*73xP_QIj*vlsC>Qgxmu%vc>?kgx`K;ZNdLuBa-vwLs{q~Xz9TlSOx0`#U;oLa0C zK9jF_mG{*8Qe2}5p{U&}-DFg)>{A?1pOgnlCXA~V#C*vovaUoC`1bs|IS^Ks{E=fT zzqZ6aO*1rsE*g5AkMFKY@lWj%XL!gZ5t8D7f72-Usur*VXDT^s6)27cvfh@%h5!fl z_(uUg6*q^vYBj^iJRl4^+ha^|s`mIzLs^(GqA#^gqvyqS)5wh*8TBV!vF-ZXSFVoo zOnJS&8W!CNzDl0?)|S0UCHs->>Sp)Su)h%!G-{%#7B7%Xht_Sp5uY6%d7(3Yrg1?f zGyv73fS?)re%#Z%IP10~?b+A1V06pt(8IXtUS6r4#?g54WGYyQx;300sxCwU>-v%3b(&cJ?n>{|5gQiu!uz~GoZNqyf zwop5KMS7Bubcd!_qNL|kPm8HtP+LI4H4U9p?^2F+#S)KFIlj%{ldvIJ) zxk9AAq)Dxl_s929VD4WhtCr$(DVxMKF-JOlLjn(HXXS&P8mS+>7R@Q=o&>xz*kww2 z{4?n&bjkz0urIGPw__;M-HTds#XRJ)TM--#+kAdK86{U$dW9eCBQH<>LW((#ho5k>ZwpU05>0uCAzT()B^mlZ)(J+E%NbKcvDKki-oseI z5(~Z!!K7e{j0$vZwqwFZsQJRPJA1$)*F+pN#Gc$a61n~9NwKWgn0{pi{vL@ebAGr1 zul(BBqx8H!@N3)-jogTsAcJ$jr?Vm#4tE!v%f}sZzo#?4k!D@n=fN}#%5iKTuR5Cm z3#3C0J%#VEW-jab<{8?BUnTmLFK2FJt_DPC9k9)6X77oHth8m?^&t}9=kTLM{z5#m zZ-9|Eqny*Z{DBXaYpvfZGf&@{OCEck)mirSEPSAkoLaZI5SNqvbhA55ob5AH$EW-{M`bjEr@iGcEwN5V$U$szwj9ORpw zGN6AUQDH7;#jKd1J8GOEvRz>xbN>}oe_L9xNOg?~wLO3;Rm@oyc~WU%$1L_#Yc1y2({uBy zX0;6lLx^v)L-&q8y?0A;xzr)eS~WJES-diOkkI9ZX;9`i_k9Pem0E!x?@d@6DMcg( zKyMl)*S|4`N2$6~xIF8V-!*CB_u!vUZ(Q`HRvxKRo%JNJU{W^J2-Qr?T3+1$E z13z4ES>w~*!Cd&nFH1LTK(z>lR@^|SIl6zFjD3PD@ErRQ1HbyWNF$!or^HV*Ts3^za@+FO7%Qmd)xW$$@5s~aaS27rUprsZ@WWfyK?p7GK#B6;F&1)JjMP~{PjTPQpH)n3>QmoWZz;`%sm?Zj5x_>JRU6q z{gb6*t`g>vXXntV-ymXTrKcY1$Irob!2L>?V74h)d$n>GKaHc{Ux2hT^B91nG|XOwG-|UcMI6F>;ygHonfiZI_KdZJXC_Sh;s6 z=@pwtk8m*y)%Qe}xXJ_$ft`!>oxKSh2ZC)OkNba;@nkQJHp;VW*VIhtRski#lCo?~tronG4{Lns zzf0#Nj~YE1ZQ`cBM#_Z+dT4Czw^^*Prn*mY#j-!~I38XT8`N(9B6tel|6yN0WJ&W; z^~BeRcrErX#J(&DoA^lVHZ@vbRZmC%70GZFWZlRw1-p3<877m zR;klrAc00xM$VPB*$KM>F=h2)27}M~_mCTe>0Hc>K>&o8a>?DZ zI4$y&9l8ex-k@Uj_Bmo4z=8H_F6L!_$f{~&>f$~C^U*M11qRp@1$J>L{RUp)^13C) zXA2#gu>pc&K)7>d&^kBCAt_6wW&uNOsBENBWkYjPx2p1|N{1X`F3=kxi+fuBbNG@P zBbYMF4`XXAR1j2ExEyN#oMkxu|l@6Q>a1^84Jg!#)xWIKbf z-MrUy6@l|kGPG$B4TLgKU6313(PD|6;LW0OSjg=KIvM7;xhTCfQVujg!O<{BGT2O; zDjG<19IpXh3GgfzvASxGz*-Jq_aH0-NC>XwNr6xlpxNPNE&PYJlc)yLlz;m_a)~4x z$e~8-0lCdTU!6Cq+W7+%DtYbHnYWE}Yl1ld851@@&diPkaJvHCv7YW<2stqSfl(Yf zH35MXLv}(0>=oa06Sna&ABFT4KzBi4fTRLcVN9@qnXqZ+z|e+IX#)oeCH@3<6ZQx* zZS_Qv{|D|AC;9S32Vmlkxd4U-5!VLvKbicVZ-Y#vtA}3uxsa1uww};_vA8RW5Y2{> zQY2O=k4kVsb(%o?qJQ}T2MnW}h?4aBtzilSk_BJXydA001n0r@WgcVjT+ zsVZl=kld&~)_YS|=K=65BRe&CODlY8zyguVs&bharV;}tWZTjjr}a}X+W3><|K^1v zrsK%2XTJu#CJ@Cy#4sS2qY|eFe3i)5feMJSo%N$`ice2v@O402zNrbm90m?Wfi4~U zc2Lbj1tM$)EM@^MhnfbFL()JRLzQ<+NMaXQm)#KVC6PL0$tEH-_kaVNoeR#rcNv$w zQ!T`}H9+02BMVv=q-5bG!)7O-A&=C- zSzy%y?rtRaTSzttr6L(U75#5SatdS*h@Tr4#( zHUoMbK*o~nb4ku<+`Le7(jQ|L+F|XGTRCE6KrNI7t|CbKp#?G~Dkv>5kv0=nU}?GC ze~?;x!m&43(T^9em}5Wu3pr)5VR`@R0TGP2n`NEmESri1?(UbG^!;I1`%D4EGcLf^ z3LM_Q0G_NtlC#)9N=t)0jI?-2FOpXzDbyYd{sNrn>YcLMLg){|6XqNgF>jZ9au&h;p zOC&vzKS4<*zluYt()*wvk9Z9QK{W0(-w^GD49hN*E~$4 zp6qy^V>p%gWPzQ~E8nJHIlLd>%=@}xy6*z{vl=jtKrp7BTX9M~oaB%XEOag3D4Qhg z%B2yCu#PP67gJL_#HP>?Eyu3BDcE^D*hRpBGLs${w7fZD^p<6x|fRHn1JUyOYy$vV@_wDDXcGsD= zBy*EFNft>KYuPt*lYtnQrjv@Z<3;aY4MgIlo{Ays_@hjZ{k@W@Ax(&&R-zXVKK?Ic zbGCoCXfKZJ1;R%i1RCW5ul{$Z2x&KmWMmhArp;}RqY(rzS?6Lt4w#L^G#a$gxKDf#==>M6W*cN9or<<4f# zgoBTju(-RJg!3f`7#a94zUc>^ihKeCab!i3GR^q*A9c~$yJVD1k!*05o*eFsEN3eO zAtmglVUJ?%t<#F%+nL)Xl?-Iv1143v#gML2K~X~&c|wuf?+D*j(`2Z9e5iL@d-OUe zqz&N*10xLDRxt-0m%qQyMMlM*uF`OafmHg34{jUbEvciy2@NuTJhMg9*_!9|;!`+x znS8|TsUd6m2FWgmqI0h#wbaFRNhyK*$dme1b?in2l~-dSIJq+EAYO475I_Q=8@^!y zeP5(4kY!Gsu7>7x>$-ocp|YQ4M?KXO;I{d>mavfC373SN1lWk*$|V^@Az$kSev z>dB@2jjQr2Esl7ldHJiFBhQ~zMO=5yzINl~61=-oPPO1yKc?xPMvU6eCZXNIswrbm zF1wS`NA+$^!^-$8s_%pLxvuAu!kI{WVO$)U^|Z~EcUH4y7>(w-5!4{wT5-a7A^g`F z4&EHuSAP-VxRLvDLzWQ(4fU?{RR%S2WZ}alEUhvzM4kODQiaVeV)LLBb;7r(gb_J8 zvxU#A9mlPO_}DDp?%&OEA6TwtB@AZ09-K{>FYJNGNv%QpEeK`elf6DiLAzHvTgBwU z01lb7I}@uC1I;I1GFcUqmtEWDYWs;nUSOu-a2qbQL-@DND6_14e2(3fde%o{%Ve<1 z@-BWMux7reLt=B@4WpJ5ttLZ1Ik-7ni<CW-zt9-NbBb_Q2Yq13U`mBNdwe)Wp z9{t@dBR%br&1USAk`)Sf(6iaPXH%#U@vLgz4zufRu2#_vkx3qwAqj=h&s?RsT02zp z&(CL;sgGUd?B`EJTL1J^EtZfB#i7Iv=}^@-XHQp<|gx{!bgU)Tmp}Y8Ck7-6?v;3FQ57|Q{a;1vIe$M1C z()Q0`?B6_QM(fo-hSUw)2aX#@)o8P!SS*$GQ;wo@cS64?Z_H0fe_cw+NpbxlDXR%L zs%Ea3*m%T2?w;Y{>NRc*05hT30@6&ZkVc#T_l=Dt}!qH;t-vC9NTJI`|l zAkWZKHkeKJQyBjpto_{s!->-w2Y|Y_G7_0a9ot<59!~Xr7W%E6ep1!>!B#-}7%lMn;MVYBgo~2T6Un;e*YcuK{3SU1n$Ryf zl^m{81+|+-M-OP&Ch0Hm0-Yd3vres^U&I^1=?9r=!Ow}u zsG06nt?Fm|t`5yw{(jMO84dWiRuV!B2Y0XM?_V}z`$R6btaqop??P|s4hZA`6Z|d> zL_1fMuRn-nDfaKHO#E?~GJ{J$wnc&FPwVLC@9(_nR6Zk?+&+Eh`h4UQdO73$AEf*v zGK-Kktwftgv=6Gm5kABu}!K=?xc_G?Ttt-EYjLn+1nPyz{G;%kOO@44(G~!aj z=_Eg9Ag-PA=ivP@1rf=UjP5`_6u%;o^UY8yGYAV^@sF==A``>xOiBsfaAOSugCKe_ zY&enqQ22x~LoIt#A5BBy2F*^{$F?l4LV;PP^dJJ8K`_nD>JC-0nC_h)YinAnuIfhN z5qaKMI91)Zg_QBjr-j;coNsh(1ozu8{VhgMm9-EVqeL#mO3Xx`(Tr!!&Xy=g7dL8; zKFClQhppNbY>xv|Lfh=Pw3MgDTSIpwj+l^1>8etl(+_4=O((Xj)>RKa!<(c!7_-** ziV6DpNy%09p-NN6bkb3~Z_=1L5lb6Fc6IfBdC#kAv=QnLB)u?$6awdF*1%Bak2llx z>lz95C_)6v%D?_uQIG34PP_F{xxGIZs&m9k<9j$O+j$+x`nqQ6>i(pWpMn0)d3HgN zyHAHbb-OIFO~Xd=LgPolrliRjpO=_gT=|399_cudyzza0PTRo2{}6ONc7s_b;dknV zBW1+le%hL)nPpC9^G2dC)!&q882fCM!`I4WM?=x(Yd!&27k3_p*=DfHhj^L(dco^#MN9CtM%RewVuJy+JEp;eILpav#liRy$h|rM0MT6 z5~ksK?b#Cns~mZ&!51f`oXHzcqdYq9doQ&Zi$|7CbKwUZ@wP`$TZdX#MP9*<@rqe^ z{2w=!4{*Xjuf1>4eD4UiW^pxZ};L=XwJdZ?R#yafRPR(;9Cc1U@Jz@G0@#hzy?U01_Uy&6j^fsPZ z$fJH6x_ukO>c8_o>AUCu7edEwRyyZiSQxil!~0nV2(iQ__lAsZ#F$F##w_@eF?fC-4qXqguah|bV?JYY|CCar$$ zzB1bXe8KrOS66sG1 z^=Ot;I<_zJms;LElY}1&39AY>TZfHv`k7S8-pDvb&unF$1~L|Qz@K!U63TqwlJk~# z-&P!a$Kx~i%=#3tx3{m@o5<%Vhysh*uf@cR24@GGb9w>DFMEU%pkXXj|B{I}xN*YE zcjJvHLfa(?Z6r5;y9X%4u_sM?Im>(NB1yx={6veC2<@PGa`8wDt1RiIO&8 zrN@mb_>Bi1fJR;K9zZU#D7e!VW!VMEAu@XFtLit+!UiZD;o^eaj@PF2f6$Ta#Usq= z)Pd{7xyc84T?k1X3ST0hnXuLmL*TJdfIl^eOBRE$Q1gDt<3#yXLnJ{1XdTR|1aq={ z6F32hd&H^U^0=G8wsL17(QRufPm7>2_}p&&HKLwpQ-@sV+@vDct;=Xn-sc1Er2ya| z#oa=IUGv)z3~I+OtS(t4WUX!5#;MY7M!H>fJF-$41$X) za%ub)8KATvwY{K+&w^Z0E(N#(G|M$NPs4Q&1T(S3!~tUt-fOM?q~7nUSRDYOAi$JB zhm26@B&@DLmIVSKAZnm5hfv8x={S-(_Cjy`&o-J$@GkT<=<)#ylMs{e>R-dn3(nmC zmGpJc2}&?GNgC>2j3HUjfJszEK_~>nswe_L8{lvOrkVBYvgU$W0SE%X5-yo2U}_>n z1EEa>Ws{wor0)~0df!Q)A z*klAAG$HorCoCkZZ!q$i3z86M&B!nz^k4mfvv;ALN=@ho6aS3@;2+||r|>n_S%<Z)(l6&NRXaJngAn)W{maY`zLiy(xz{jOMCy%@xcG_MXI5C8!HOBftjL*Uxb z+|YLd7YZDTu)-U$q&%@W;LfcI?24e5)PxnztG*!=w5#qMS@G*o8W3E12p)U+z@UVI zOO-XGZy}!CtQONU~m_}A7=Mp)Q)7Hyjd_LZEL&Qif&Eytt;H5!Em#S4B+B`v|1?IFC?Bq zWG)BeYHwNc6QG|Y@Ne#o>jL6|vKTPde{*U;KiEql1_6%ji-}^vVD1+Nj{6T;A!83n zS^DP}Bf{JDe;5Qa`U%s&)CW?alak|Cgc<~?2yA{JFt3LU!(|c!WSZIOz_TT5P=%bd z{{FpOWP)j3WWegph2{refnsU(BnHTJqZO|K|8%ha$r?(2=IOgmxyTtJynghD_YQz7 z3qTs)>@Wr_#Nf3;fl&_d`6s<~!Ux1#41+&{5p2BXVi=f(1}6CfjJ-!-8vKI=fcyXi&yWp<=1KPh1L`uW6F^p!qqo5W22`xT{i4w%wCX*S^Q3dt z40sn8C><2tG)d4a`L$H)bSLBklerWVP!?eGfz|*`0*$Z$9sZXn{XZBB-2K2Ai8N>Z zKMNq)#(8i1;__PZp@<)&@TZT`E=l5ROtbBtUdVM9cuj!yo zCjdq$eXcpr+WGJ!{f&sGrK15XMMmRWbG#;bjUg*}c3zB9JpK=WzfwS89Edq7Gcj#m zA9l~-o%V>u#gg+rcip(}>}+cH7vd>5$QAy_bXSl^v)Su3$fH@l| zUv7U;2WQ?IoIMIL;8aECzC@OKCay;L&;>mm%qLy)C_ki2`2WInnrvA}9yuz|F20d@!8 zMtUoFX_(@Dlkrgs1)FGB_%Ebb}<5r zq&~RY$8&qRpb(IID%Q%*>XG*I`0Jr0{vgd#78lT zhz2h9kEX^d^76K>Udmklk`D_?zu!h=1;@2D{aZT4nlXWzoy0qZ*f#2oeD$OrndSc*w-+HfSU3hz# zu->v)nIY?8;JW{@xGqeaKWXOzYesykI@-sELY+1K>G03N6!Z5pU|>uo=3C|SYm^;f zfdL~QQI|^iB)(cegn#!8s;A`KbhdEjm;Dl#Vb}a^17?*N z>FZX=mF4xO2X4@Fm5=Ctya{#0M{Lyh9~uiNvWD|tSOR4J`3p@OdgaDDR#+o-#J-y!FBetBd*-%eSy zjcQ~@JmYHFza_^1zS_SYp-L^_^ z=SQrrvv8K4^zf!;zy~h`9FI7kluC4vAJE-K z#Wn3T#atoG#I~CbRkME7PJpE|z3&?rHXX;@&i#&j$j|y;jC0{rk(*ja?C^l=tN-!& zV%HhmaZT*JYz`i)E6yKJG>RIHjOmsqUU|!$b>(U2CKWBR`pBGoTxAdJn(cc*N!$c#q%5Jf>rkko4GLfIYqo5FebNZN&i{)M8+QO%Nc5E8l zk7nF0kc$KDzFygSX_)LMc9Hq?rm=f>^Ryef??=Bn}hvI{gp1IeePt*hmm^IxMe*l{wl=62BgV>vd;&cx`T^W_NjA zl`-U5eCYC`R_4x^SI482{$T~5g7kwS{nZ*Ny~ApTY@rG#l}yWf;>LB8%BpPH|6RKN zmS~+wtIX%aL^SM1_{_N0iB!%b8Rasd7g`SUr&g|B<*!k-<4>E-MY0zbCFf$f@aZ>S z71Jp)ue7dSr@2h;`Nbg<5fezi5|esZ<}z!V+PgC&VC*9|zictArQ23+51eir-7Z>8 zevjs88HUimn2(4{cvH9BB+bbO$E{lp`=v6j8jICLs`m5?hKq91j;d_Z)v#xGRaI+P=N;r?lw5~;)gVoc4v zCDIjWsbnIga?q3#iC%Yq0#8N?XdJzsdf>`=mrp)+0kj$*ChB4F%hC+qmx9-19r+A_ zEbyt00;rx?An@M?Bxdd++5)JxZn%KwyY7QtQXL3Xe0Yo_LP6~>gqc)CT#y*@P*=Ql zIsVJMvjf`V^b?TV=_-<`gNidj_8}=}3O1-R(0`-i?9bCSxd>@c!pyLy9IN zRjb)(GfKc`k#vpO!60;1kb+hNHs-m~>jU*G|fQ5mq%pU1QJNE|aW4*2{HwTNmWkP@Oc#q0d%2R&(zUs79ar14E8V~>mh|YiH0{Log6Q%3FJmD6ZfnFeRe_= zAnQCp0F*l**g;(dDrrFosrM*ohlt^#c*Uk2$?9^TD{7Rtv&cvrb#|Cuw8D86C(YYH zS-Z3`Lnw|WGTEr4wJYb!4Yz+*dMn6 zS9_E>2O@_rqlLA?$^kbn;+Qv^iWm^VLed6A)wEXBK$Q!4%1b`tT=yk^%@#nsCp9rD zUz4gO#US*+iV~y@sT070z<{lmNg`2*(t7^z8&*w{^fV6gTWvrUq4uw2 zBJ(0;|E##kq^i*9YGVHJzNCOITM)Heh+P9wNhIB03glnosYB-0P=D;5ogjUa=R(+z zZco~+AS^`AHB5IfINE z6-4b^A+A45nclv~U$8;k8D(?0C<>@W6KACvxPx|{gF2yq6blf;VICZoOp{9rgmmSS zn&?yz>`PAapgphkKoiqRD7+^d$+(oX28-3XFecSWz20hlM8Dr0R4PqQ9G|gyq%2=Vj1}JT4MTZ&CcWB zdOUB%l1sHXwpOq9)2aG7hVw5HRIUAM z9)yM`xl{VF_Z2y%z?z#8bR8pO8KG9xCSvlp;TubkrgwLC{+!`$z`l&9TPxusV z(=l^+wUkb`_8H@At<9tJpO3$iK$-jHpL+9(8Z}}%)9idGPAiTFF)IWl;arc0Y?&X` z4u3=FT)#=RZ?ci%mt79mIDTQ#pAdkVJ&x74u9)KVy)Ii{P~Bs)<}LY}>)SdF1xC7H zU7WvB;4H-gOTj{*dP)%h0_-TK!H2YGArNxwG z&*Ie2o!VkOGP8yav{=Hs=ly)$9=rLt)>7HWI9A<;OQLHQw!_V|W^vX-oAwIZW<7T@ zLj0hi9os?s@ttQU;>)8ogUbgehN(S@OGD^yKvDWxtgH~x?(_8WA>1rWD)IG;lY?E% z$zT*bUX;995B6+CKvHN^@KAcCdg-_(+$%Tfdsz&B%%#N1tt?|vVO1b2^loV`BBo=y z0%3}F8W+x-i)&8c@4%d$hM{cV)LkAQi(P$>G$EMeUHo+Q42iMNNA;KF5XV7ChgQy+68dU$v*phsI|-uf)n<8}ubz-+v9mOJpSHco?VUZD86_$h*kv3lsHYD@@ zbo~XJ-tn-$uNWV51W^zFE*i+b@@Y8G!rHWm{m^u-se;UV)9$jky6bx^t5#n(a`<0L z`itB!^x2A^4D3nLKKU^ZLa=gl(|WHJPb4Huq)VZF-d9{_6^$G=WRbXNjjnca;%akI z>~#j`lc!*vv1KOTqcw9u>GxAgv4}=z>-h)6r2~ze=7Ac&8HYz4v8k)MGf=hFG>4x$ za1p0hnTj%wwzU~5b`~n{C@%z_82;FEQ8Q^8u6D3+2y@uUq7}0akKvbT0Q%@#`*~2v zQ+-Vn^yu94BOP__nGGegY+wA1-1k4e?6AI3pa&7Lkd0z;-0ZLza;Krz<2uKY9(gsB z=wx?h5RWz?hvV45!gaDfDE+@{aX=MrO{+nxA2~O_stgU~g4!Gw^pcaAu_(SqTz$=B zKN)t~j0mQ#l@lpH!&Do?Z*vA2q{0w4IR;(!%DH|!q5L=))4#GljC8GjV~GhTKTBau z_woA^EVIr(#vbC)sHw~01p6iSmIZ>;e>%}B=^v2}s-1s@5a{iHS3@MwNCs{O2-u!U zXbNcl_2%CEZ+wVL2zZfS7qcByBH;p{xB}%SfUxw!P=1KsFkN|^-^K@)v~>La_;JO+ ztnBB#nt^uqO@;er zE~kBtYJX~N;>6-|tTQ+)8`!<+*!Db?r^npVE)Bri{6BwzQ_1C-czj~*G_Xp@3E~A64 zJag$?ba*uhs%FaUv~vdh6grb z{}J`oVNJGwyi*h`K#-6UrAH}^)Ig*=C#@pQKyrY>L=+SWk&+zU8`2Fb-AKa->F%z1 z?!CWro%4rYmoVYky(jMPC&7z#BPxzdnu%`3Lp4PS(*nSnuBKS~gWs3gvq~8fItbF~ z&xJwpCWMa*^c-FO3I!~}HNvvqz2N~q=u#lRyF`Ha2$ikiSN*q!|3PQ}0bmML*ZxB{ z3A?-hU_8RR2DAhC*Wmxf``I6G#JmS13WQWm`4S*m^uok^`spFEH+6!wo9!Nhy*gpb zMi_1o8n+(ob`8-{O9{3VAtL;&q_nTPiWZ&r>&>4ecnAqYTvP=#KpuvV15i>Xv67tU zT#6#719ibFlaGr!O{#;#FeZvV!vu2yWh^8d0}lId;Zz3U^DMH5$Oo%>YL2UGUk37F zXrohyDnz}%ALQ78*bo;@1-{)vVF&>Kzw@ZcHh1&SHhAQ4b%u5-HiB_3qZy)26b8WY z=F3zD{w(WfRrVOol&k*(C5??$L3x24VP!Kjn0>$no>4h2GUG_*{d8^`8fY~bphfj>ZfVH?ttwj zg$Lby55Rz_BY=Q0HlQQ@L@gcy~)1 zG9@MoK1#?6#G(c?DeHos-i`rMmD-A_EU?S|kKecwllJW^*%b_wy&g0cK$fHLX&1v{ zFfI60dzCZ?B(#p%b~Q2h(_3&k6A4q=5!*fn1NQsUsG1x|Gn6<|7@P}t(}n*-LQ8L` zgKlTgU8?7%c?AQxaznjO<$v@5lfTM;7c&@FGrOst_g#KxE1c5;u1hd+fErqYLK}?3 zui;y|gjVn862VZ?`vfrl3Ns&+JqMr$MAflWxB6f85xtvKRvcH42PF@-8H-`y@61uq z@<2Et0dfGv1%e8SOX8VnKynRMDhojFfDR+F`-Rkz<#>0QE1f+jh3IPT<4kZ*Ao?0? zM|duP2Lu(QDziPiC9hKlT?dv$Sx6Izx`opc|7sIYe-1i*4IbVOM92B5JNLmhNM;qL z$&*|#OYEL&HW3bg z%OhR(Np@ct;i+NELWLK?7$!Ho9FkcUwliatO!c@7h_A2#=g^A`Hdmk6&OCFlL$OYq zIz3=HlP>Lvlco(e)51TAMIQ|1yUF)aE?(O_AEvaFRMK<>DSpB)LTL?fHD@w26>eYS zGU-M0|3PGNg=a@5)7#%QZr-hL`^M`Cm$4>i)X$xhoqnT^`Yk8>$GMRPX}HsU_}!d0 z=cgafw~=;)=Rv|*ba%x4_jWw@fv2YCP1+_M`g4e~axZZ6!?=c=MFt(duXZ|80eS9-#k{h74@&+rNvy_aXW%)Kw zT*pIhbQD$U5_XVQ__Jvi5%rwg`4hgGT+XNk4A6{TF zGNK+Onkuce3twM0adY7!8i=p5nyGPs_CMR?Cu<=g4RO(za^X^A@Pa4xI~~r3VgFFJ~_mA=MVY-3|!)Sv4OifwvbIJjv7#F2Xx z!R?igz?L!hMRg1fDZ`7X5fibGf$6MMt?t_=)1oaJ(-_^@UlkM&P#f3C{`9pd9pn*- z{)3n|)K$DOqJMBRMR~w_*A(!w6 zuj5_r`S?0ieTeCQ?tB;v`v{5-&N&kU5dn)EYVopUO{Y24)z4nHITrCqM0bqRjb{1SM8B2@-Og;FnXI$mn51=(< zqNHn4o{!ZnFaDTKg%k`cAtxWml4LW&nI6D!Vir?-z(wojk>|8S(`u5s;<=rjRKc4K z@jM;$S*)Uta*FAtioI9!3wLa=@o2qdynCo2nWvlWAH+lmHDCzZSkok)ITYSH z+hS%P&@uW$h^v*sJG}4VPn+s&zsG>IaxvTdWQ0)@%SLrXd3;;|K=Q>EPr6N=`$iZtDwJgCG`$Nx*}|gF?_}BVW86K zE%X-iis@8!bFGSJ_xU9%R80kJ_~Ui}zpccb$zD*zq$|91Rm=lhy*N9qUNp)2LdWao zFZ}#D%s+??4a67m4_LDJ!u2x?>Du-IKLLVS1?B{T9E;I zoSuD8iPlx0r(HRPCpW(Sqsl}VK=#1{dnP-`UQ?l%4EJqp(CYcn6h^!{40=hNdB8Cz z27`7}lP^n323im4P8z;2_C z1ht^-Ax-zAzqny|08Fx`y`Oa5hd4Zy##a+R%x#9t8C}Aibu0ez>}lDY)*MRv#w0j3 zr~!0JQtvUX^*mA4rB%h~j;fDoj<1OE9&YMGuLh1zY_VN#F-zMy9t$lUN`lnPP z=e|B?!$&8JB%n)U9lrR}yN@JA_p z%hi5n`(w{WgH!2+LvHeHr%J$!v0HCvlng;0bJG#pF}AJxRk-))<;$XYmM;R60nBT3{%lIC%xnSdl127O}Ly4s;}1_U?85T{TU;LQ_7RkGw3{ zHt-JRrM%=Kb!Y7foVds7E?eAhmWA(g$vhT#3WNpTOa31O)nXTa`#Q?$A7t`d^#xK7 z@%X;LhKzfr=B5w7t*lFh4{^HXrTE2Zim*)6N5+LOGNS7^s@64e-udJ3w6Bb!%fgO!nA>=9*g)IcFaKnS3Dep! zkqAoMi&&k>Ce(_Mw-du^e_%C#l1szJ?w|GT)9J2h)fRv0t}0Dt?-8qht~b+PxcEsq zMvR<+j80EvxjH%0Ij4ojV7y~&D(8BELz1U7ze3ToWJ3k!+9?BH3F~h)bR9C0erTVL zxrMdw-MSvHTtf=(-jiE1PtBfSU*|oJ5Iwl}hJK+|EiEc}6%UPdc-z7kB=cc0(V*R_ z^AfRUHumVFm=jFUyI zt^AFu)f@8S-SH1p&$C(Vpc>pz=NftXJH)XasLhcVGyfoDw^uxJaOqIfv1D z__Ami$oB6E(cAk`~ozXFEHl zf9JzbQ?B;;{j{bM;*3vBjSE|v8iEOmtnbcbXCsW7sAo z&RZj=^2BslG~5`OsF6BhL;U2UIDv?tcTUh)Sdw8FP4pky<1q1zeW<;_b*!1+0fjXBm`lsIjFn z%BJl+F9P)b^agFLJHDz6wwuRYEUEj+!ukCUq@Pmhz)QOY%@mjAX&GNNOx--Teg}OS z0yhA?D<7u!_5;=c#5bGUupKM|E~bhVkhVGv>j@2X9R>5HF@16Zd&rqsL4Ji~#I<|h z7jrg1_iy?OCq_ipY#FQw8`HaStMBUA;`27Q^W1WJg@xT3*&?P7Hg6NO9v@~9dr|fC z0O{WcOQ3p6e&jMD6uwFm7T-}CTLB$EDoIuvPqEpSA`Ta_oTHfWQqgWTeGW+>0cp)fS!E-q8{qBB8P;vb|M z8uN7p$$#fev`t8KLiox(d|FkVmbRE~v~7xl-Z{lPl$5?+4 zZeI%p9uAxdE$KIu`?p7qhwZafu_0K4*jw3G?$yFm>>}IW&{#cct9{_U}FXc23@%3pLgj}E5;r0tyVPD|+F=Yjjo2QG8by*})dH3jG z!=Uis+1mzg>E5=bmx!|zPm8_aOe;UM-97uPiK7q^{ZdLqV17DZl-!?8j|sOrQPT9f zm((Zu4Pgv7oAzFQRDGw?MR5f3fdUKZInrN8qF;R=`g4@XXettcDKPIzWNR3h@$ka);bu(G;jhn{cfrtNPB`D=< zQKfo;QfKC=)*~MuU#{RqK9+=I^BJXfzM5@s{fMB#7e?b*p`z%bWTI4 zHZL9Fzmncv8C94s^}+WweFgsq`fn9cE3Z>67Mvd?WiN=IhP3vJa_*dB( zOUeGb01LU-rO1P992TuP$7Oa}U3)O5x?q}&R@Hi95VE|_^BL~iY46o@Wo}|9ea58O zY`S{oV&?!G3?dZXw-7C8B6GEA{T8=IM843J@C_DL8(-?4vDE!Jqf zk$U;vri@wTrj}|dan;p{_Yb)Zo{O_ApOL-)P#|LMqHCgxUZZ8)*3xV}9Z-s;@pBfa zegl7#zw%_0PKaNW=WF*jv9|$W1Mwn1sHV(8EiN@8`aG)zo{gblFAYB6eXR^0|8B

pQJW=ASQOqe3t{qr`V<_#fP--{Mc_}((i{qpA46L<9%n*s&!;9r^~Uy z2f!zXqZQGNyKkpH-(_|upV3jluDsk3qU2cMZN@7|@so)6>S?h3nq;J)O3@z??Z;`c z32sb;mTt_uz=i8L=Cq^fC_*HE1OF8AF{p^8A55KZ>#VWV_2zHzeg;oX64D6l5KSJQ z6y*-$gE-Gfqa=E~O3yy4n#kMYP*p?$9T9_%(x7b_SeK6)96UwCr2_0F(n-aiiG&cL zk4$(;+)OiKw(dx%7K8+WyM~^9lk_z^Ssr70r&zZfRT{2mtu=O$#S1D}tOln>>8A%3 zozH0{+hD70Tbodx9|+b!?&&uO;Q+HPAM0?pU0yDRyR$3p`|G|AVitc=D-0ZjdG;hl z%@P*Y`r~ECl>`9w!PU`h^!n%D#q6@OZ=3G#*kyM#bJs+{f)A_S7WX8Jj zYn?W1Mo!vUG@2aseu3lL z!F3RDn;Cqa!#9HC1VpJHpoMO7k&_AtR; zpi$2DkX!{7HpkGi=%A5cD`0~DThK)fm#l;0pQ0z6;_x=7VhhUG`kXRYvUZc;n_?%6 z>FuT$(06}i2^>xt&<(>ZA0GMWEYuI|`cA9LD%wGt^lWc$l=ee^<-kOU=oBQWK2Q@N zdMZdxX2~AcxX_-9idv(#RtL?y+YdWc{589Q05_1(op$L76Gn~*3HHT6%$*JN(I*7O ziS{2^W&##TP#UWf>R$PAPc}D>2S5R%?2R)M1~{Xe3PD7DT>*$TzCod;2zynCwjH#+ z{OgNmL1or4kM)q?AkO%1W zj2jDjZlnHTo+G=3NOU+$w;v)tc?_ha>Q~jB zCI(kTD<-qv8Gnrg`j761d`EUrIc{8ZE+h)HZ7|mn6eqR)H;f_N&rEp`PGZQMT)7m> z1uN_E+Oq*S6@YExa88qhHKC%hV80?K9Q7Z(>QA0QwLIcR2&ATr2?p8=0&;(8Q1`sX z4g$dMV0le~IJXq>9_L*%Dwb`1N?%}m3HqM|3A{N1bWaf6{ugo~M5PCW?ZnWmjLF>r z(#!N*X~_cR@9x?OsJeju&B}BFk_|qCM>kZtK$^C$Jcyo`!+N}m5eMbEv^|nmU+|xcHMg*dC9N^sqBL&bDz4Rw2he-j0MA8j}KJ3K) zfT+`Zm(>q|;yVgZ@QM!8cz^?^MGDUXnXrxm&~inAbB&t!8?A9LSkb|84}z}u{tb1o z1Q2EsGSPlijiSaQDthQ+pydJq?z#}r0L+zgy;xMAxf!T{fEEUz_XpJfM)+7%LY9oDzm7AoT*WKSvP&pecf2lRUB&jTmC7J;M`VxU)ev1HjnH* zF!X@v{{NVm(p3Z@MFE7j3~cE^fA*2QnK{IzvHFlNjuuQ`TiO6#qmibD;Yj5XK1cTz zN^>LS(SZCn1~Agqm_xXp@MckdM|ba;k+3Jl$QqGnl9(T0*Pl>_{@wNac@}&885r8~ zT5_=~-$s=qCfPz7-wB}?jQr?^_z=&N_^qA|mdgp_`zcpn+K=K#Yc|dr%_;&>^LH3{ zY!dy9unhXi&@#2pDUK~0zcvo?>8%Tqui7G1)1-D8B2>=h!++aMJW%WW;C!;|$e^lp5)Obogx>vh6abDm4^CY~CM82O_e?ra!8bK^;_bWC0WpB{_TK-+ep4+?u zAs$#Ii|4141BH{W0>@m;{WYYtMq*vtJ=%h<*YI1JE~m>{8-NypFFj^@+@4iWXFesyKuNyUTaK#xCYjn9bZNhnW~nX zYrDx3Zo51QlEbYE0Y9)+E9|)vbg@oog!}^LD&M8;NgTTOoF}V)-MFPoo;APRr%=mS zRhLvi3 z@K6hV?hV#&)u`(>8_S(NgD*_0;c_zxl^cZtYDeD8NosVk&{xq9F@Iu@#2x(-M+76) z(VnyV77Aa3_Y*Dz8;um~p0ssb3)A;AtfX@fRfL+!G`@b_bU8;k56OPpw|H*zBJD51 z_OGM5tNJT$;vb}r!$G%GEjs%q($1ZA)$J0|Uh}h&{W?yqP?<(asjgAhUeb!~%h@{L z>8#EM=Ocy!cz$5`IEII3mla&|R$GrN^8vaalv<>0p=I(JnXEL;b8>?i9%NKw@YJE| ziGO&kznOJ-ek1Qy_G%l)oy3@ntKK_`inyYn5)X_9%L}TSxM9&=rcj1URkLRN-HuCj zPvt~!CDgyI(9+v7^&~}3L0_TBCo1Bz-&$JVNq&axe*GBMtl#vd`Zb>`PwmH`L*?I?Oh^c}QZe=K}<_e0Mo z%u)3SGQ(B{Q9Oe~y}se5@m~BE^~-{SyB;I~3LY{-V}}W5dHz3ehX)%WBfNHXSCRlE zp7AJ~T{ICiLQ8Csg`wqjj&X|)4-a1fyD@!2W6E2!slJSG@9Dz}4`65v%Sn@dVn(Lz zUmZ+JbqS@$yduA1{?T@Z_fG<_M#@nyovJX~!q$T~n_PVZ?B8ybRpOJl!iq^%VcStF zwdWN~E=R=T=eGE%ek(**0cz^q9aG`2roXehE0WpU&vw4TbaY5yjhcUvZeHOUfvg|> zP&JTV{72Iaz08(u7j7OzjNyx9vH|@rS`C_oK)8iLNQCZ6X8oTMCk8+?oa&d4-V3tN zUWXo7te7Jno{oV&Q*ggitP^eJvpJXYGt2MFdSDX=`_koH2zr2DF*otT-ugQ9mHOiY z50wztLMEul;p(u*;8qj zN**&spLoG_gJA{%S39R4cl>@j18~yP4mAP%GzBam=a!c4~d~ zw{1*P?;Hx@`}7PpYlWPEyY%i{15@a$6ao!_t};2e+J1vX2(0 zK2J=loU5c7POA$^HA%kPdYFMY7aw=qdiLCKDbVF2``&7xuJF07ya_lPM^KH?uo+Wd z54?!;w;|X{k#oB;zN`(%Ty57?>FuD+bnrJ1I}>fn?q80OizJkAU!h71ew{)V{`-c^ zH1i;O<-!gxWF36^3$_xuG_ZBU;u@;;)E8vqcnvadFbGcX^;le7w++(vC9}f08Pu3P zF;P;|$ox7_GH)QHqOwYym5rIScVW{jkdr4q5yG(!V~;KQa>0=mccFF$Oz}Kv+W?Nz z`q+R2p*B(9*&=LOf-YEat3w?qYR`M3+E?>Y<-aRW`^~O>&P=bu|EZYl8Q$u4pAv!X z@O(tA%)kun7x%%F_s(4taL+Sdk+KTN_&L2l{_x^z9*c>9FdM0_J?323aO=xY>w$)~ z8q~7Lmzf>#dIpQrmH6=;lb-_D0M??Z5~10NJl~4~04EEFtyeB;_Itt#E&c;f)BtJ(fa~>u2#v6J z&agPWjnz}r9r$=~UmH(>=|Q*93N~g&UI}M7$q{4yyB9HD$!UGo)ddJY4Wx`9?jrgi z36+a4`@QL0ov%*HCxQ1$T#wf`tGg0(FM8N32zjW!Ik70{wQ}^)#ZawU7qenE{i$J| zMCjr9S-k#!oX{|5vMN$^^?9b7Y-%Wj%)M4z`k@D*bh?nia(%cEtn?K>RR@N~dA@zg zhNT?PN{sND@qa&rsuA1MQ;^)Fe)wVbQ+~B8Np(09_GmVb0`8vZTP!_2MU}yZ9G_f! zHmV}bAja}uGQ9TcYg+h#sisv#tf#I$o;Y5v`Bc%>C1&5sWUoo7^xmA#>liGh6&j zerp{~e!TYS+eF8~Cwxb_@`4w`t^Em#8V|mGX1GA-uAK~r#R-Yb+jpS7$m1p2iA&uR zFN$R*4sv4xl#FJ%-qzhSysE_Q)q0fBM{fLg0-oyi>CpiH?ZnwfkJoVHmDiQJkB7r& zo|^BzRG>p%YiKsR2$suUUS7MU+6h7<(0?WaEn~yxC9Zkj0g!?yi-6{m|HF+A$x&huM?UQgObMNaL%MP(@o6M>)G>B;)WEzr% zyVXr5$-&S6*Bw`gppwAaf&DBZ$~y;#y0N)`yl3fj=BKN~ITn-;zxf=gMLhMmn|$Wp zr>%mX4Hn@jSWJ;yEccsJvP8I~ObKaLbN}JfZ1yg#h5!47a7pG(NeM9?kHWNz_$~!4JE?>)~a$@p)vceIdvnliyxke~kHU$6Jqt`cjE-fXu zn+o%{<1ydi$mji{F-&Urv?hD44pmtndLa_82H`pzYb$6o)&0 z!5TQMvBNW;yD_Gfn|shYY3cGQ8s@1qp}yC8v=$tO_lk8yoDAwtvZYkQ@4elS~9-yMuMAFfrfZuzqgi^B#q-@&Q9U@XeH8?{>_ zu+mPl+pR7V3ss+Id2f`doTBK>`1k&r851_v&d#~PfI_iHPLAKL@m3-aN+LBSPc7%^ zYMW=}-#O`qaq8?@Z`$?}ZGlGWR;}7M^8+e-q=oK3zdx;bxFGobys^aTuPC0Qy6zr+ zm;uIZr0=RJR`0hdaTRY}S&%g3I_w#&-POInp(E}0M7|J{RS|Xa6~tm-=!noh*>t|Z z3v4Jgce5Q^(8*DmM)z_zR>tOgu@o9f^Z~b}i?db9eq3qCUJ3nn+qiO~@ovlYtOL^9 zlXSW~o@${*r4b?5A7yVrlzQqK+OQ}+4_{5Bp>DljvFCRHQRn_?q0s{W3El#}?KuZe!`uXFEvqv-=FuFsXEj>=VG|S8$mPNSD#oSVe z%}TSIz9XoB=Z5F()L;G zT9w0$N7rg43dX%GW+s9vj)Kl)rk5}-NIl_t6S3_U+TAwLs2iPD7VhN3S!nh36wd0I zYQt3@rMP;3?23~?Biw3ccZ8;R(+YOq&tCvFJuynt^U>#uL_xN_^?UPO9Q2=R=gYa05%ntd#Gs2d($U^2!HF z1-FdDU97_KRl!9sY)4Ag&1so@d~7gKd$zFF#*t#Pv5pGftyYrcb-9%TtfjfOhywrs zva(Na0N;o5I_A9c2#u!mjXP^^?U>Au9JcVx7V=3<^b>KZ{&GFD%iWxjgNJYB+!?}& zzf6+(Vl}>OsONzd)KvwzH` zsF8GQSJE3q1!dmXatqzLL|R}bxU={5&Hk!G+V;L`yial3c|lyy^#!+;tu@oBO0C08 zu%13Er5v~yoM-JIgGer$&)Q$Cqs!OEC`RFo_sx^@D%J%lm(gK^%(1}NU0v{ifVLU` z6^(k|BYu233@t)ht0k1i|EJPF@{e1KR+;`M|79An?wpkovNr$d$K&5uGfqdC3&c)6 zz)Uaz;ElfUIu8k^hEW6){j+%+U#w0ec`XTOvUv7ua8vXsA|c$93@*%BMd2HbiW?H8Ys0Npnc}~zn3m8H=JI}Wd0bM z(HZZV$zInNJ%-L^RwOxv+t~Pth-XY()Aiimm@FDo+AEZ)2v*6Ycv>^>N=26Bg~dHB ziSHk5<`(>6)$`g%tb}<%FUPK1%4l9y8`7+I=1K2`nk-W10R76H1AQq0TIX>P4* zv+OLbn2fUnYR!!=rZr+1B}yqQHFeVWcaZtL@x+49p}lftUi^a-+@UFf_vfTan6*%Q z!_OGG;fMls0B0U7JtIt3@Vyz}MIIM}WKB-UUxs z6=H-ERc!YZ!Qf+^TfQQ7VhVLhY})_^<@9e1W>2QCb+Y^*N}Q>G>8q6Keaie@#FL(Z zy7a>)$s%JA$=N^121-?>s5H^2-SobS#l@jG^A`P@u!D(%ulNMjWd)lP9E_g|tvS?b z@wP(mj2U0&@eH;dJ|PG+PF-XYI}GH;9x?(g6X^$aR?ov7wa$JTdG+`ma%Z8j8X$AZ zNi^3f=45*j`?&^tW)fuiVNp*MX=e!r_E!k_;})00y)o{o-=iH6|`}%47gD6^o+d~uin#@ z8lbE!-b?XK{G2N!80jKj@uaY%P-I|PLR*FP`=;b0za?hgFlk?&r15)uHfLVg@@;QF z+IX+ew=Ab4Mq){FgjGA_m_J173}P^YtWKmGbxORAQWO(G($0iqf z^ZZNR*lZi;6WgDtX>}BaS4`KWe0egcKaxsU!h&KYP~+&@#%``LQ+uyOH3xOl*Kwo^zUBqX1 zmq!uDA^+TxL9!qKz(k4vAk$APTutn%LVj2&5YgfH&fdTuczE!2WiEJnE?-}pit@X? zsDvQPwL?0shb(**n;wOI*g1j2X8HJzCd`|Pyis0(2EV6u4xb z%&NrhYzrZpo5dFWF9rH@FSQ~N&AvM()qauOSK|#d8CaJT8Pr|L;tmQb^+k3JfvO=J z7U)n?AGtoP!d=+;ale%tKXpJ``?c^zET`ss>5^s#=FYI^bZ6Nl@9d$xyoI$RCBej| z0{3PAqL!b-1$z3~SxZ6*O_P^Mx|OBSy7$W$ zh@@s5Hzus%5pm8tF>;J&vhhF2^WGczoST`yOphFOjobP~@0a)Qw?rGHhE}zZ4gkp_ z7?xpe=XUWu5!tvg$zSBL5A>mDhth6qc&~!TPOr}N>JMSHoO_s?7Y-XVnFa}-)Jj{@ zLOr4=LWrUQq!q!CMBu1^J?Z}$tN#PxbqVR}Du5*5&|rrOgZ|Wv%ybf`RfwuBtA|8n zFyx5>I}~tG>;U&Cge!sn{*qwbhKT9vbqEfCw*j?nCVY2LnHBe*!$ZC^>`QW-@Vk&ZnlrgjMd-WT#^)BB173tDj#>S_~pU?&GVO#8Jj2gqeM1IGnqQdJ*dQTKnBJsuSSAz?4WZ2w1L0-gxM&-E*X z{(1@#h&}*Dd&uQ)!H;YqYy_sY^sg;o9v8pHLk0dz^uDA(2Lj8r?LaXxFbk|gZaX1L zm!6c4-z)(X8G)RGlJZ?41jK;vL4|<#2m)9+;4X^^0cWNVaOJ!M){?$UD&62L`HxBk z=OIMfmhcwtrhUIkrT0g1I{qD(?djf#VDW5%sM`LOig_^<>qN}p?7YITC99&z;0_;T*0Zas!!n0>$$Aae*$=3 zre#vSTXFBD)Ua}15Y~}cVwIw=mokMdWTv5yUSY-Q<+b!#vDG^+wl|b)eT%~9`I{CNDep*CwmG|$-X~zpuHD4#aa|RIovZN)m?d4KK^fo?qX8Yv*^u( zn<1rz!a+5z_Lga@-$~ZR$g-=m>|)?5_P=T~{od?jV;)ksL^zu0Gx%I>qrUHk8a>Uv zAlhub_#qsmJVc9saRl;*!Sv|?ogGCjWY(i5Bbj?*@szk1{~-Lk_&a;*WD*W)HK^m0 zvgC(Hb1ZR89u+b?{<9uo!+(pImVRR8B^xA&^osh}6?TW}vqyr1S~M|-28O*|-6ykE zQBj3EVyYn^m5DX;*D48B6ezbtaO~Pl9>d+zSMx>NjAHw2Fy7lD)>FGCNOA`Lg@eVI zMq{SK!gTrE90Xn;Ji>Jm{n z)%;W@rtWiNwkJ@71)JrsZ~a{ku*y>>)rlkOq2)$5AwGNK=~XpV)ve=B>}Zm3L3L2V z@gjHGM>LnQ=vp*`leo0!g`G#Y(Ag6lgT$M^jfhCPKIY0%+d`N{K!fI)PWMK z?xq)k*48J*qu6+TnT zs9pL2$HL4~#GmrV-IV>ZVXdZp={5cfB^7d>UDsQ$)@eH2YgMQWoby=7n2}o>H28F` ze@RSpbg70z+gBYh(}$7`DDP ziSuiB0sH*kW5e>$G~6UF+R-LVR$Oiut$A+vW5=Mu!6Y1P;f>;ZKap%TZS9OpddVV^!V#Ea~WS;gA3mGN>_ns+ny0 zHqWp0`yY;#6T3PaaCuZJP{Xt)EvXc~6obf?E@80S&95Aw&$%PbGQXDKq=F!Jzwtp;-*24}21 zzKd=r8wI378VTA}6tZy#oM~qxYFVa6Q%2c`O?^G>9dr#r;F2FPex#K;ZncqF96l+Y zU5Qn*vyS&gf1A>Ae7>=AuvF&_8n^1J4NMWyL0}-u7jQCDwjwUG)ir zEwn+gK%Lk)Ih{Gz4AN){-t`-t2>WWt9EARytJWv(*zh~3OVt=rN?$xF(wvRWQdk%$XR=1o5pG)fTDEFJT+Qdn$0h54&C1 z(i}42uDHv$+{Vjg)EETH7#yGPm7x0*;FPutQcCHg&whs5*Rbu$!XCqZYjA#iR1vZ1 zd}4PVofngjQOQAQB(NIxPP0`w?&&O_elDpbqje+hW%3nxI@FXP_SW{B*jQMLK)wK* zJ657jaePzy3F+Fd&3mGGe01-`F}$bx+q10~21vg5K~jfn`UgM0**5q6joYG_Q#{eq zp<}5gzkBH-7Pwvp+*>bphpJxKktJDEn7wg!0r$G5_(6E*;WIF>dT>1!Z|$r^8S5A_ zux_sazjkQD*}P%vm%zn=*kRy;>T|f$$R=`uMJ<(kojV|#1CHV?eM|)a&}zFWAq~6+c?Gg%$^eSZR{i2c|9IyOZ+xZ7jMO_AqcBoW%rY$3mskjC||WrQ<&QZ3%LEqKm{hFn%=N zT{%*4p?G9bXP%T-7yk>N%wqdx=IQ53r=_yjvGF1}bE#_IkbaZu_X)TCd(T?@qYG5* zCL5~3qpxI#=jxw%jp^M^=HqQ@+Mv?AsqebIZ+`y%_qzDGfKsp%LZ;E>TIH9no8b?; zmXPLAy2tJ4-><`ua;V}ahU|E;aY)}7KlENtpop7RV~+9Z)s?e86u*OBOVL#|q&dv@ zJl#HbX4GOMx5oVqvEu$rT^?XrDe&#~9aTDyIhnjobx7<4$B#7m3+>Q52jpk7x$O-6 zNP`Ulu}Rr_EKJk>m8xXnZPRv}EEN}Gc@`|W)-2KK$o(m{L5d#SXP={axLvLZ<|6KM z?I4^eT2}QOFlefOJrI2BP9IDX^K+iR`YAIPTv+@e4vD9%Q?e1nix@9i4D!#qf14?< z{3Z8}M@G^!?l;f<372j}=S*zi&k5nqDyna+AwTA(g`-<~yduvHcwxf1`0bq6sJi%g zMrYECfp|6&-}E9g%1ak3LMLUfDc=q)kDKaXLvNf+yWP@qHr{Jbb5ELGZEN;g%2E(N zhwR@UN8Vskt>`v$4l0F8jXK-Bx;aFmcS0Z85*$uN*1D)78jcRlRFU$dQquN$HW$dF zrp$niT;&lasxB)PAw`jG(t5Sa3{hV3xW^S8n8bPJ6zmf|>%5JnXtzFhsM^u}2WhH0 z3_r0AdE)~Bh^HUDaK^q7zG-i$Ctc{lKsQ^Hq^L1<*K<1XjU!N~q>PY0|K*hKd6qYZ zo!z`{{pX4fZ(%iQ3cr@Yy@MMQ%h}t>KES}for~G2^tC(kjHUS&A@z`Et_3flV?`CI z`I%B^Q~dX?U2m?y;3i^Wx0DC6EE*=;4yzq z-VriANi}yaOg?Kl`@m%J0DGj)u>bu}M3T|xh3mkJ!6K!eDuteMTGV<3n9_ep8A_L7g?;+ zGQeGVzn_pCxm?)8TY@!MQe*hY#-^^=(d&h1hSPRP7nv?>jErM566`tll0N^jbD~Rr z^EqL2bBT#Tgen-#F>LYu)yB$xzNg}wB%2^HUW$X0EFFN?R$+~g$;&nHC-}0FV-Ka# zr1FJtb79$OIS2nBPL*p#)o>@Y5NcU5TAJmz1;q_X9wy92w|hNNdWSXGQnk2>Y3^q(cr)EvWU2To!6&pa z>l(Ab{^g3&w+b0SOJm9*XZ0dH+*hKZ;BkKp5mcaR(rv0H`z*eZogQQ!^S@>z%B9n8pHOPYo%1c`D!^P zKOL7@tGq;7StB#kW#tmQ)D<$MR~*T{>Vc=9I=VG2a4{i`nzCOi92MDLZ`d2Q`11*y z@OxFJSMt23JcTH1TF0~uJpDA$_-cSmrqgFiHf8s%mpV9$4wC@3;vMsEQRd;QP9{;c zl~+h39bHjYN2>~tpR?87SMuyoqSFUKK%YeXqpa@95X=KnHV?^_gfOT^gk2S1yEI87 z!uNzvhI3%H0zO_)^-U`wStxu#@!hVJV8!>1XbV%{zmnwk^X4`&y6d>nWR*2Diy%|- zNx_9zVZ3<3$M`7rt@~dlmJS5{reSA5PmxN$Atm$6edbQNXf=8*yuY$$51%9?c9Z}_ zj~vw|MvSHbFwDbY%hR+TazFCORt(fet(wu7Kk3apb;s5?_ zhT>U=X>Xq_EWf)1FDqvQj@7*j_IChX7}KT?p889GE7Vby=3qzL%v4xA(`6Y z7jOBCtqHJw@V#@v6FYnjp*iQgUB!qx$WPzSy?&*;Cg%fcuJzpEdjmT*DWQrJWE}~Q z{Qj-7>|xH#Uqo%biq7!pmVY6d?P@sY_UY)=1`)!e`UavHkjSrYIq#eL7{1+;%N*Y- z8(XBhiH_){NM)Q$-C9%OY5J3D=2+UP`;FT>xIpHwW$pTX8yTQag2&R*WOrNhL_u7Y zcrPvOV4rNBI&@~o+f4MD!Gi91q)5swvS=~QGl$#9W`3wn#AAOQFa#O29Px!?JS5B& zBdYWhH#iH=_nKYBT0MT9!r|%S4kTeuJ9c`_Dnn5%iP4KeR)^y$rKog zwb6fl8nTW_Y-?i9r+1in8R?|F>h2nz*@d2X%zQMD3U%p!vfHu7ENOsJxLm_WFX~`K z?KN?YZ67#%0z_^>iG!BZ*Za5bp2+C6Oo2@a*K|~stwDKN`9O*ov)|Jz|A(sgj;Hef z|9}sYBF&@hQ)C<~vdL)Jd&@|XaqKO!N>nE!J6jxkWshSNA#{vmWpA>R>~qfNeqZ(d zJ?{JdgB}uH<9%K4*X#Lujz#4UN5&UjHJnkk2#4x`?hJOG@artTB(IJ&#&^?ZR}JHo z(l1Tc6CIx43;IL0>y^MB3ARjl&8L{ghdBG|qF{5|8)*5%ZvH5PbxL5~aL-+CyBit= z8}U6_SR*4Gm39x%{jp4C7kupT0)!TP>(e4NN!IqF(FdBMLpa&?lfI~t1}2T`sC`=< zpW7mCN1x%XTZZ2l4)VrK+H>DNt$*_4B^I%@Fl4A%Q1Gr`+0@gI(K>gRUS>VJHrn=$6W8M7vie=Z zP0)2mjdB&(JKb&+ls@9q^!_$0=I-{=!AH@Br`KmHY8w34f%>49yBc%ZsXaA*#Kc#6 zOQylkNP~I8vwk3jx)qGVqR7m?cLoe>e-6BM0}klhdYN47Rmno!Cps z-FQzO*FHDtPfx_ed>@xh^|~r>6WG0P42qO-YE{|09=ZO`#&t*Pr!Lo4)4e-kv#H^+ zQck^?8VcBxB~R8(Dy!?O-ujm&jeY22*i7{>xvGi7%I_0iKbfLe?rtFq1X+lO>!|Hx?IeZ}zy;{Tx?6rwZ2irAC zAk4R3xn&VhADlGAhy!T?rRj#r3}Ls+5rHQ6i4M_n&v#1uEL@urM_3Wn3xrdQD;u6& z&TQh2g-_lHeRjhxEfR{Q^fY(wDF;Sjg6zssCdLb$lvi9`KAf)}aPTg2%3fpgCAOue zH`X|?>olXUDpXtVMn|y;HW@STm|WYv)4=}LXnP`5F8l+g?7N<~q=P!(-(?*C1lOq{ z&8uZz15o$V^Qnj@bUou%nLu#s#%U&OEyeSDet%q>gw`Bfx@c{j1}W3d&_C;1>TG&? zcit4Y08q~Nm#EC18!3q{2*mE=R$S$u`R_SPbnvhTTK1X~r1NVD<<43tGG>yf>WN}g zMX;8XV3aHKH|bq`nQXCmVl-Re^Utq9rCkF;Po|5aI> zY&^@q=?xI zy$wjj2!`vug?Imze8BjjnE*iU&p?i((AWozp8l7j0oRd#3H@*a0JM>RA$RCsfDa(3 zft-x~iH)+rce%4-g3m*rE~f#;FK7(J-p>PB6$N+Rpc|NSv`duyPpKgUx`!iF9BhHB zo6e|KWR$vCtf2+A=ys^fs0t)Dr(=RCKtv@O^4k()ii$E7_UchVTpUoW0BO@>`n(Rs zQKGOqh_Z!-U(9Dsbe}4EI(5B2OBLm&(N0D48>IV+RAFd8)&?l~Il-je#;@UH(mKYS zuK%52rQ5*+SlRDtoMwtZ}$pL8*IV8RTF(g2I1-?3!4d0+v zg=vD>3>@}q5Vc5sUp@>U!wt>B;Fshx2{?J$&-Qx20}3X9#OQxG3f#LL%!GqE=VX02 zi&mutLp9y`Sa6@hslhMHN{q*3p30MUZu6XvMSJ&mVZGht&*gw?e?J-N3q0QbIVQV- zRxD2UMME&T0z)QRRi6Kpu3iP!j!X~;u%LSe?kHY&mbfMXt%i0O5(CXtRKfHDW|;s) zVFB6M&E>&)LFh3!!~|gW zn+5VUK>8?Hqh`7T8ktnk`U0a$AQ(ypGNN|44Va>VLxnzgo(+2kjK55exlO2oMUq#G z#ib3!1tW#;W@?`bVM4_${7J%!ho?d&*0pHAhkCx|P0CrjMr#h-Ia3#KZ^!>K=o69(;Se`z`RNXgV)X40!a#V19pBar61u@(h}p| z5iQe&jMH%q8h8b!s&{N#ObrKgFUzR(VharIzGL!q4Hw@+qrj(l8*p0S1fd5COg@3j z2(X`qMry$C8H}(%W-K+WfQFRB)Py~|wBPxvBd5GjAGLGkWkrheIp4$X$10-SRMhW6 z)`0(}dw<=w|Ggxjd!qXiatqXe+_|>@Bp|H#8cEwnZjbz4m6*LYXso>#t=^TsP(q_Z zfhY}bnA$$+Ip(HIOJZJb^!e+k zZ3DehY)^(R2Q{fA-$n&LCE6{6T%faReIvm%2KoErfqQA{DM3E;i@THklx84~OUT4o zYey^qH4w3J&0Cz6h=kdC_z%~9wC`WVmp`4t5}UHo9SK}-o2>~-s*%CcWru2WQ&lFl z#Q#9ewXPdQ_n?!g7KH&Sh6vZV4Hj(8Kt9U~f#YgQpmkgTLJnWwa?!pgzwx=j{>MAm z0+Jd5XXTu`oSyY5D^D#ccFE|;hLndkwXm}FT#yGr{Bqt&#YMR^1<{R4fiCL=g+IPD z7e=yQ(U#&?wfiaF>4w4ERO3G5tA|TV;Cy;gkN>dn{MZr5teULnR3dC$$GVLwv7 z`o$IMlvy}SD^mR_j%iQv@LNu4huc%8JTKrk_1FA1omFD)aLvdu%0oQq)1oH=U$N?& zdH%&6t!L3Uby~VZ5Vy%C2t1*^MQ(1~$wn4J?x%lzW+u_4;RNhx7#q@?yzywO7JTgk8~qWMl4RVY>2g8q#i ztG0_;6$Rr`Rj)EsYZuggwZ#vtU5KZQE*ftY()HG8T~#$A$y}LPktBKbPIYk%Rj5w7 zNU{}%iClBp)^YVqe>UqjAT6oU@HLtw4$v~b+_Qf!VRoE zuSo$*1Y779fzsH3Li~Gah7#z1txK1T~ zFN5tSRgBlFWFAdViNp5X&&QU74ci3Bf@Tt_(T5h!dQOoiH}hpg&8u zbxMv#+u_5AC|7+$N_T>e<188Cdr|9)17URcF4GB4gYyGTvZo_m^QKa?<~eSP%t2A< zdRt}dChOO(=PyvW%n^B?jvspTO{Z(lk9EbU6a7XnMs`ocm;cElW<3h>`xD=9?^EkH zT+&p4rpXU^yqCJN+MT?}S(jl@7h!D^7&!Y`mRKZ$t)2FkGts$`n{v;7#p>#7Oa3+| z?Fn}ubK0IGe$z^PR&ApF|+IMi~Jh{z^uj2Wm|kfwN2*oK8@+mZY?q4 zq1RDzX;#zE9JG{K=CMAGtgN0ofT}&pBalJNIN3)=A%hwVQIm#T)v+5};e};Yiy?Td z215UN+NX_2WK5@xHwh+nEWiNSy^U1zL%+(zTe`_X+5CRb6Q&2>w1htAdAp4+7l>#u zqw0e`RGwG4m-olY%xFJnl&}|cav0Q+e4N%}Hq$N6Wh{=Jl>xzd)<1=;j#3}R@8pL zdf#Hlc56vjzIk^j>skQTEn+iDGhTgAb6|<)`PZ6)<=$&KK2LmpMi<6Ux(j+oxv0)s z1(Y;YDc1VGc}v&UQ7H7gL#{OkbyK|fq2^qz>gIOxs|(4m-`8AQVp5b?SEd!u=RZH% zCMGsNu#^CgPwNoRly>X%tDNU$Qo!5Vl^BZY_gXz*kz61BUFz3qkf zyS4ND2kYS?SV@o!h9f+Mt(|iwGLE*WNL`v5&N6x5>#&>Mny*NOJTZ0S$|(wNlnqD%EG}P`+JDqAIB5i_@1VNtoY=jZ^@tNr217 z-tPTdmu&0thnj9PM^P*0ROp-f)$a~(?$Q%`19!GFc8?9tcro#6Fsj*vPCJF4LcdYM z4W_Q3ztq?JrV=(sKdx$*eAiE267ytVp1E5;;gbX!^eL|L{Q`fDOEZY>iN@-av8f*M z0=eE#mUW&07WgikiYTLNatW~WY}?O^$a$!CD&};2-Di4^*SooCuQD1ueuYlUI_J@i z8&?RtXUMq`{NYkxzg5Vpna$F!kHFB1#P6MBn<__92E6e=DaXYv>GzTbMyG6vtM86{c*jZn9#PYY!X%e!d~&P-z^cIh>IztGv)jkJ!Z*m%W;|SzePL+onQ1XRX#nP4aPt<^0a19bCE# zkO9VJ7jGhP6=~Q4xMhHl=%CrR2I|f$5Ab5{A3wc_6O#FmPHcDARp&^2E+EN;C`IzR zhe&f9N3c8uVjbd*pnZpk296v8Z_Z$K{Bw&>RcgBlu-{s|k-_>t$1oK&zKOB7vtKwR zj*)pRR^7Trl5xFj8+T+Jzw5fhzSET@iDnu#J;g!3G2r#negXOl>HE zVRO!485@2x*1urj?pTFpN)uwb9%X$2X+7t=KAPHJnkBa7!)QG^_U8++|Lls~RNqm% zo4E7$lZQVxwB`7y*PNXBmp&>o5- zlHd9+$XoHN`1KP7(gwwUu={fO^3Je5P498Z<4xA->iS&dz%0UvIJCshVJgRMcs(_r zy@`J@EMbM;@4gv{D#z=pa*xCBW4Tqv6C<{bX1ilcY=EqT_n^7|PyfDDtDrljQkL(k zMI;D(3)Q?y0(rN%N|hGS`Dbm4Vo;;+$^-k{TJt4d5MSp|XktmczMWXbS&z<~%gvY# zuRs)(Mn7Z+nGJ*-w@c- zQllqV4>c|}2ryYOM_!--LlU6mPv54T>fU_B&@~ay0A7;{;sn+1Z0;$B^-o>~EaUaO z?|gR64Lm|7qC4qy4Bue33=z+qHqFyt(x7s#c`rVz+dR0tYG(Jg)@d@O9H`T%4o9DS zRP3PgbS%9X(-`@LHU8`)WqU&LQcjO*#vV@Y&n0um+bPelRDW>qjBNS+-S7D*+i$98 zW6!fPmdwKwHaX*Ns%K1M1KLQPEhnNXrJgi%k~j;!gw5~jxM~&Vy%i9qWN~Mx7RfuQ zJi%19n-82^d39s`-p2#A!q^FI+w(HgTazX08%wlnaMCl;AFDcX1HD6?%zIRCc8D{( z>t^m&{`}ZO%XQMv+_ZVKm}Mm^>VORO=PgGo@QUygC%F?2kA{x?1MsO3jd@XfSn+wK z#M8Zx@tIqejgjq(QL>|z$czX#T}2Y=$awc&3l9_hS^JGDP>DU2JZj$g4>rIxUAOr< zBeB}6<~DsXr{a=o`3hneM^)Bzv+U+2{EC3Q!$;Cc->`!BK=-HBtMm7~Kez_E=WUY> z8PU}`o*32i%bhba3VbN?EhX2AIpC?qenFAsN6sO289m)AY85i`f@kC!`LWA4y^2E; z2!$$cO{8iBVmgn@&Dq<}VL`1fqItbItI$N5R}8^tS?r=Uj8D6o;^P4-uv^2w&7bCb0c!A)U!R^yuzeEG|c5WxTJR>A$X&^Nc{VmjsWVFRbx9f z@cb+N$?Zz(Tvxj|xw;2mlzBMbbsdnkT(ht2n$WFGm79g%Bv!fu*jsdP>ZQn2n+2f@ zWw$Tv7bR6&{3)pt-8$>9^gO><&0(>d%q)D%gE%-@@MqJkdb)Ujr>Uffv^h%U@R~WF zsxZV%%b+fo^&t%Nr3+P!>c4ESN` zWthzIDXxDbwaoJ7jHau3#k!mWd>k#_iSd}jFuWU&y-}Cd%J_pf|H0VX6V|KCdzAut z8OOfY?o>KUI_?@gwXxyDrF9k*YoVdyE7 z=UHG4C@p3Nsm>ucPpPhH*@>HV0xm}fac8bBcH}0Yj|7*>_6K3|aD;meQyLy~Kfq*w z{N9E6&&T-JUtbzYte&y;KFD9ynwB$BrSI264UOObn;XRzjt3-UfQR*yb>sCS*e(J0 z7_^ZzWdA}7*9P5ocrrJP!i%?b1OvF!`M|IoLfSOwL2JwIgt;lK4X=iuQ`PxBpgGA+ zR-Xw9LT;wYKUu*50yw9m1o?skCa5Zu*94!X6iWzZzPFh>pa7GIsM1NM{5u!_3#k32 zO+%nX4nU0lf5=)W#Jc{6x&6Og`~T222=fEfXz(*Q*bSU`a`cSXZE*Mi55nZ+EI7f$ z!a*o2rC1u|>YtDrEIyri=I3&JCr(BF^um$uWgp#CU0^(8Ajs)=a8%TbLZh2~`c)Z2+i{eU12tN)o+s zcFBpvH;9B)>Hf9H-(iwUu$ap{9iqU&51_M}B+W^a;A?OIV#L{i&;`6M8m6tF27jSn zq_5uyEaia}Pdho8=I7kOe6ooM_~W7X4GP@0Z>`OkvpvCa=d=Ud&EzidB!^HfhDGdP6fMt|r61XNJRjJh=v-jSNcd~xjbRPR{;yBAY zv1JGj}ruH^F`Sp3ZG5jfJjoT5$!uIXeICBdxM+<@a zjt-mMxu^zSO)7lds(`hl*nU3YsD`*Nn$@ax6pC|q(%?7zRT4SFUQt*DO)V6lCzxau;`P{KPLPaV*C>O;0XK3=T4FvDZy!yP${+|)Zc zrDEc9Qy%<7d4`8fm*xJHdTeq`I8O%fM#l3gDDUo?EI4z|j5NxjDBmXcA_+qba|ahX z>J=nQ7g|qD#(}maA*oYts@MhIQB+K5+5Hw|GDG{wEhR_BX-HQYS6&IC8NFA)V0NL^ zJ4|FsYE_{FfXr47 zTY}N$5%03OXj}UO!_fee;Nl&*2<#Z6B#`z?L_OE24y3hL60woc>`_7UUE> z_6kG{J+6tEk4|wAQREPld_5yz5r+CYmY5;;*9W!*!X}*^Pc$?`%wIs;PHI<-c%s(x{d=} zGed%-XQ$JCJe{)+X#mUkcxiw%nZ_qhf8JHQ?rRrs~ z&WAg@+Nup1Z5x|iD7MKypKe|&&A;6GM(Pv9 zD#0OHRcT2_n{ZC>REU3^9ejD!yvIDSx?~Jz#b0<<>w{2Q2y4^2oMHlg+SALiBHd%8 zA%V>~LykYg(($pc7I6~q>)7J!fbaMS=3fP*C6m_LUto!`K3&*XUA&Y3wdbG?Ltplw z4vROI>RXaMe+HR6UoGjx(GtHgpvx)-O9@h4`-t|+`Sl}-mvNdkOf+4b#Ch|%(f#80 zp1udQzb^H$ID~z|CNtd2e&Uh5xxrAn`7N!nor}^m+U!}ogudR-2zJ{meP&@+wTGzq z{=@WEeD^cPkz4$jQ_X-<;IZ5!C2F8t;By=Gk-MF{M27RTdCx9!czxYSGXKHl`lP6R z)PzHe#rf6efewK8+1!iLdRc^_Ph3r>rEe}(~ueU1y!Q@b&W@PMr2K%h8vx~49DYRvqj zJElyNw|}E_(;6)&U~u&M>~uYCVCx$1dQnEDs?+qn<-3E)^KJ87Jdt!F0w{JkUN>6h z(c2H;MgQ5~?X0Quo|gCOgZEumecbC$*1zR0r!j{LlSXyM-(SMxn@5~_+BsnM za^1Q*opx++&yE2|SQ1Kn^9i-W)*fjgFZ6|#JwPC2GB?oFWHJh=$e+hCfI%P#{sE;6 zG>G5;vzg$_iSVQxFtkk3Jf#h@%bbq{VNrQX4DmH((+63~kGRITXywn4WrFPVs#+Y# zQ!>L}0>7y%n=>X6xaJM2fGUJcqz)KA>ZxQ>;%l!SD{Ygc z7NQt@3gkBrNO)~(;}^A0M-Mv(f){IBHP?Q4i?8>E+@OxiN>#?t%*%j?Ueci0N1yMb z`xK9UtmPv8U@pGA*TI5xnWhA5Vsz(^fSa+1O-w)CKogJ#(EZS>o(yVOWc-e8N#6|7 z;;V34T~?_Bqwa!aVJ&UHcgg7^vuzTIrBtfL8r&V@TG~=}jmoPD=3gpj&he<+(c!)I z9nfNa!SZ%-?)7o?#OUw zl-<8Fi&fJDwtYA%z_gU@M%t6W(uzek+`4S~)nl=A``It)W5%vwuf!J5@s}J5>}MAD z9zP!u(-5%3TKYu-AGfOHI!4@UjAY(up7sLc;4bhOjt}k1A;!e#2pMej(+3 zTf3by5sw{AFdkAIMG_J0u!PwymcwF}jhS|35B2+phUc0yLP3&Wc#+i2@D5RS_WXr1 zM8uQD!7p;tnBk5pX&Vip-hDKCY;1}dqG>NLbRbK<$1eN_ef!7FPW$=B5fY>GK8X_? z_7sk&W)uxvLu|riGFh;r6WP?Qw4~8IE&C_Z1;WZocXMXcTvutnPw3|}VHUP2!maY? z%4thes${w!M*QePoe$FHeHUr;ZaJd7&$-%KAos1}=#xJm&HPyOP{+dgb{sE^&pmPe zB)eU0y~Y?~yj>d{g?;JkIuUn%*3Y}xBfz~o2+vX2p47Z+liYtlq@vDg=Jxv_p4F;N z`I*hCw0%YLi1kqE`xN1^grdX(w)iZk?jM*AFJU{wg7RqR({959uLollT3+*WJf2v& z6BKaaSJZuyhuPs!seyOVLgWA%p%Fu3<~VIc?ym+;bAenwvd?z1>8V2|30XI)#o7_B zl=9Mphp#PVilj8$k7AdT`s8LLHpeS-;&bAsns-xE^)y?Dj58duO+_Wi$NVV&SJ8B} z6mPjY6_{tAk22vNl@D=NT3UKDy|%p`7+2aqu09ZS&OF=y_juuP&CcqKOOw+1a7sMc zbGyJN2ezk(vr>VgT!foO#e#z@^*`l0V!`wJ>JiP>x5Z|q>C?%TNaOnaHLwwnSq>Y7 zzZ4-m>?|nt8*c4uS(-gq)xim?FJbcYPj04JADOF8=G4eK{`$>^z|vDO>=#nCF}^w3 z@gcF~jTfP$iW@wXzu|U+FWeuLt#;ab6@Tyz?c0ZAw(URGZF=#Fm9+)E%wWRD^XX25 z?QhP~^=k<|xhd8`(-)JN=smTi-3+ov7v2UcYYVb(E5a65jfK?*#SVy4dK%X!0}^D1 z>r-ex17cmMSMoQhIEHFgmkVi0GR9t3gQdoRKI<#C$&i-)GO~RKA zH#_i_wNlC9b1DYQ{E1~KH^z$S#Nhl%KX(PEytiy~Pn9nqHZxXKNjGa1Saq*2+A`>L z!cAshA4VRJo8BwnX*OlI3L#uSJ{hHpsJ2955?QTm?O*g&yfFCbXmZs_Zea~^{FAq| zg{MLNiz#pQ1^SKpJ(5AE={L)G#7UE|`PH0~Hqq4R2Z)t%N&i1)%*j_{?j^Q*0AU{^ zw-q%MJ`B>{{udL+or9x5w9B8-IOUnS;M1d)3@m%Sfm9XnJo@!Fr$F}x&rF8hleI^x z0FKBLHO4Kcs<_AfzzPCH=4Dcz+Er1#&}|5QnJxeY$RP7uSYJ;K_!dPnH`qA=!{=oS z2+iZ?zs?ExDBgi4PW&*b*knq8OhEmR{&Q4`U3DlGAS`2 zDeV7<1ONBuRj7%Bz5#Ft9AK9KgJA_=84QPz2gt*i9*ANA@h689${ar&7E7@0ltHF~ zF8s>Ki-Ua7)W_+lM9Wi3PCcZu$;HC}JtGh7v!Hwb8|~Lle}X$eafGvNS(w1k;25Cp z|M87Ha)UraOrAgX{5IH6JA1IxXl-u-Hh(^tPHeX!1vnhTR3FK1G6%-R!9Xzf{OJJ= z3^+q@u5@h5MVB5${MgU`2|s57T`3ULNGUNNOeWtw0N%j%;B19~iry|OFM=*hx_OVB zEeFTJ52Mf1Lydu}j9&)*c{?yg<|qGqSrVWY7L)?6(oI0y3$UWUT#qy0Z~l>doZxFP z8{}>Kd&n>VKfF*2QIQV;aql4Ek3$N&A_3#Fn;e2y?=dtR=yclKASZ*a!Ar?&yT>w5 zgZy_mtkmexUJ8(8Brxp)p!?3G9a^RH378(5L^Nr-Gx%tq0-TDM5U~X6siA;EKu3Y; z?gHWc84VaUR7R!s)IdhUUD+aTSg-5XPQTK|DcW^qQhL#-pwIr3n`@K5G^o7=Uy07? z*zc8-0@Vf_8##UtfCbR00dfln=7vrb0uypTjbaD796Er8(B1%?1F|1X`4Sj_1?ZrK zRB$k6`~Wx-Y9tvPmJMgt(ZIo^(03t7!x9an1SkkdpgX4n02UzUhYl7LHcMlqVR24O znBay{9(d>sV*ZysYeM8muzSpXw|9o=0BdiksGrz`&f!?zfYu-t^Q`HO`g_w zJYH{|!M;!-lO0~3`wuq#6eSnRkT7=;YO+ochreB^Lbth^*+wQ6`iX_(DpsxE z?Di8n(LXoKtdbVr(qomv(_bdsZit_&*EW<4x^~0#5HZ3Rr~xifsl#DW-p;$zjnxJ& zSfV$S;i{W^7SkK7oIR-l{ zAi#c7A=nWRN1dI#hZLKyKM=M~K|Ro9X>zE>R~s)!N(ZHUpS!zhcGV&0*A9OGbs7EQ zD5qFV9P`PwtKG?@ccPIe)$xz6CFb4VeL8}qn|fAGVdv;^aMO@vS?8VivWO?H{pS1b zTHD`s$HS_%P6wf0T60fXUtqwl7EVj*0w8vTYeVjnp>0dURV2~Xp#k5r&`Rk7E_;Mq zLsR_1nvpI)=6l%<_A|4nlp7EeO7OO|Dn#CV5-%K?}Wz9N(m<)(GUD#DB1h6jy7#^O~7Bg3#Dc`-_TN^Vi(+6u*}o4r=SwO_^VncUpBt#+f^Muai|Yc;^@4uTiEXk>SxPZ zE^o5ey_c5K9yWoo9{s;?;YN7|ueH-Y}n*qGH(&{AGEFZG`| zp1_T&EqCv$(TyihEfU>uUT%f$_Wso!?bibtN-et$5{~Bvnk@vQBNe>dKb`PJkiN(r zZrPXLj*WY)DzUv;@BP{~(OX)wUBjukM|fj$A!<8$rPi9lZ`a6kW^caf?32~PptC}b zTa4UGm0k%Pi3MLX1c?ss)#x)GV&B+R8pQN;9k7wgD!p5s>KTnZ12g zM%9p>lkw`~(OjRg7P$kQlZq4V-UsxmiSf+xQ60&k)i|iLThwP?No)X60x0>+MOCN! z?sgid$`FK%*RQmZ&pomJd?%xU)^WlCSLwiazu&`n`nueXY@_TtU@M_>E*-rdX`)gU zMU@743TxtJE{|BbUG(01?pc_eo?CM}%Rl4x$}*u)g9~A$Rmz(IoWldCK(EX9mhfXV zQSp`S!?ur@6hoeMleQU!MaOr}vp%;T2~U@+$oaiQ@lNNcie&dtNY{AEGT1y1F6o}# z`GfN``9_;%Uh4N%sioRI9Z{$DJQyz~Sz5SqZQQeeLTbw`($6UREl`RaGnQET{t0n# z%HJ_^DK2&58gow(KNq>DzTA|rp(^uTaX<~-UpwGZYPtJ3G%cWE0NEjXw;)YHL$q<^ z_XmJ%B<4F;U!~QpycoB+;5;s*(JpvScc&&M1QbNKz;>qXp@uuv4+akyu*V^}$-dIr z%kFUq(1QIN5Mj-9^%lrdmK}93(lvq6MxBUGEZ97&!h)%_Rl$D@wxgVHfa$9MfQqfo zHB=J(a8bxQaoaMOg-@uxJiAWCW9U3J(VmYHc`qIS5^(C4=OQ1nMIKkf1b{~kw2=a; zsE#7iJ6?MTl$HbXmrZet-7yLZf8^aykrtwdLIMi; zUppjFn4AJc<^+BX9I%C1MpI4a0;id!g5ORHPPc>4=`M%kcWZ)~lFd6}K%|EP@tz-ZP0JFc6*w$nF9f@cEYOejpkg z%ISqFDl*hiuwE#P6N%~sK?me9X<*Dk3u-QTI3evLs%jgI&vq1m8xUv#KnOPni@^a;88BU}1A)Y^ML@2&{e!nTy(2n%x$|h4pka8jDmM(&e4rdxi&YX~gsCT+ z55)m!O4WoC_$>)&a7eb6iq!<_WE^18Fl%U0fT1V|35I-Zpu!1MUQYq1IQZd9pmrXR z@7(c_KXccRrzcGBC3m~*Lq@|HcI&3+kPDL!BR3eWL1zOIxM>9x$AK>uj(I?78nhm& zW?){*odY!>%m1q&v(R8H_;)Y`Lf^p=af43^a7$2RwTmUZpai8gn2SQ#-{14o7P14g zKJe>RPw|5q5PTcdw@?6gJM`7xk1D7{{5P3`{tSbn$^Z2$S)fjYx)G>)1SU!l@}~=` zPPB=zJZ%<~f&y~Fz(r9}19y8I3P=GZbR3z8Zei(2uJT;U(n(W6oHjY|Vrmy;idItu zem+3WEKTLSSq1x$)0N3m^_sW_a~D{1VTyodY(v*N1Z1z{V4PwDsw#jY2pul}^>aEQ zn(EF7lVnHj+fDrRP(!7SRNc%x^#x21|K`F&!hmF?fsungT>Hjim_1VPSx%y=>a--yF7aK;b$L zJTB1dijp6k;gw_|rC$Tel+GO02#*ZHqo zR$Y-ltC_3!ldKB#G{6VU#0kc5R4@eHZR+!28ZGkl-;FXMrUeCim}DTMrDK!DA0z77AiuRH~;89KnxA zQHB2F*7)O(#M?nRZYD~E0Is1R)lE_F3CxuE3Dq8G9ik&hA{th|Dqr5N$lvZXc`;f0 zt86bPwicgVrYofUO??o5uf?k%-kx8KG=EEs=ApHP!SdU>vKvJ)?E!3a4^w`{G^8=< zgw97!TQsGTPln;#T$tZuG5K9=tU7hTfygqWog~_2ae*;<(0!=byP-Fsc0`x&(gRL* zvYN*vudf;|G8mFZx1-}zpCccjlB*u@VsO#CIbF|s3U`fw{HWf?NIaE5b za|B})L0ZMP=aM&`9GD)JC~>A6nWyj1QJ6G7yZKvoTe9GeL{R?(aW2CodtSy;nIpOV zlGp}=)o612Zo?M*IBug@sc>z_v?JkIy@>HejMc(k!5txX9RFDK*ub|@m`eCYoSwmF_O9L2;4vzpv&$B?Rp)Xoo!Od5%a*>z z{;L$Bb~2BBHbZ1#Iypq7`OxMo2Ox|dJ`?$$jb2-N7?Pr*e(f#a~-9{&EbirT;G*b8&MB&Gr{HI)M z(8g72j7{Zz_V3~|auHUyfHbp~4^NV4cVgz#*vPGW=VYRH+1Y3Hkt{2nIWaYYqdT%d z8|A%ppmx(-s7T5l)%tO*L^t8%MrlJ0A{z*Bse z1+_|~JoIykxy6k2-|Xmjfv1OWQSp1kr=W>j#JEw(CyW!1%-G6$n7?{_DXr`=PhpCu zK;VnugZa6a4z+Gs>|H9$8YT)xRb9x@yUr_hEKPPOMCYQ8Sd|O)+Z{p=^{E8>XtW$@6HKuyD+XUf)Et`~lbu3V!y*bN#5k8*#6ClIH@L$wpyNV2-v6Fy%u zhrSKDg&p3Oiq5e?;s6P5BSS^;X7oSUqMW}BL(rd#_OFzd5hhJ#goeHUU?)Am-?&}d zqEWVbRkybCQJB`e^yV#+4Dfd~+eRCwDI;arwdK-0{T|77XQ;0Do7bLbp4JI(^#G^2 zG}kiyutY1Ac{NivS>9nn2!6$UKP;$!z;sab%Q++SEPI`sI<2^ax`Q%l7LD%H?@@4q z;l%cJmtz~H#ji%-UEqg}uvLjQ{Jo@P{8ZlP!nc#oCO5wD;NA-%{{A-ZRb(Vjzo zA2n$2K^~w|oW&)~SJ!J_)TYZZkFvBstj0b!Iv){6Uh`GQ!19u}v_l%>_~t>Sh@;=; z>hY*d@z2(;+46ln&37qf<4&BseOg6&CD+aAnl_8%?{rR2?RJ$RHJcgL3OA$`(gUvZ zOguCWu)j^~b1)*79MSmB@DsXZHW7333=m#?15X$Cvg%9;qvVti>3s^?GX>@jLVu6q3GZK$F1o`PM z$3-OoL^JLR_#!9iQ}IyT0GM=+3}{@rUc2f!|#i8h}|S)G>^;U)()_{pI|=733p2#Jj3nAp?7 zEWtB=abWPLnQ%4qWhK&v;q!75nA9S@0iF#Kx!oaWNVKj7C$KYx)Q0Hi!9|C9++-3t z^duftZnEF>V|{U@*J`#jgwZ-s6(TX$yf&Zc(u4I9PL>3!L3)0zaRXqgTiKa&siKI0 z3+)_9-DaJMuiVQ#^F<_S3i5JnmmGCQRsow(6G~=nP=csvJ(wZrkD3Fxgbe8mG4nXI zSQ=v{uDxZ|ns&NzMXo!ufGyd$a#3|>@p1fYKbgmcv8|^eekz}4<5vIV7XU9wKT2B# z@7Beqk(x6m&y-u9;RN6Tp96RGR9Lmmi+-oBwBS>s61`wt@N9TSn>#ev(UY-nx)az1@$;uT`xcL zG#)AhO39M_P<@q)RH3x>SIX$OKp;H_xv~iT=$6}Uu^F7T@YTV z3S#rBU^>a*VN5`qoPq;RC8WOo+xn2>b$}QdJg3lv=Ec7r=wC_ve?1fEr=Xtd@5f(V zDD;p1A?DDm2eOj|*ZzM!&);?-P8am`Oe$Kr{S>G#YDi38cBpO@84Cvz)SiDwRO-5e z+17?f`D7TnlcBgHdSQLf&(LcFv`mcv9ROCtd7FILe6kSf{7#(O3uTXkeAu`hg@=>H zNIJqkKL00~1~+9v)vPK3zz*5`@g&cj1FI#Ae2j!W46r5OAXx(*Y^H7Q&Oq(FgSotekn+}Z;z0(l}Q(2$--DS$4pJ_|@+$?vr}afpk|LMfSpC_6Hg zhX!aQY!X3YCCpocTO-bM zXT#&_fz>el3Pe)@-S&CAoXn_%7qq~b7+fq`sbrv72Z1E+ioIWqT)w;Ykq5J9rLo-> zG9+Dz1c8ZhP$r}^YUsm+{CNe#-sN1qf-2a!kk(Bnct6yZ?MBVz0$>7k7!U=L&(WaP z3CCB~RI3MGPBDpKc=T;T3GSu-9U^gTa;L7eh=YjM|kg1rTDUl!45b95M?4@^LVWfjS>R8qTBu^BY0XK4ID=r~&wJ zUlqkoZnvmlUeb{5?~H-kE3ovzK>{%|^drzx+VIzun>P#0sv9_1uiOFtV{d&H%#7tk ztzbOn%3VnFAKQkGIT5qteJ7v&5G%^gmrSk3G3ms$*)Ym?ey!!@gmwAreom6jdqAxX z7_H#00ZlyA9OAe!IdHOq?1jyNvbxd(XVgEm_p~Z_tdnZ+|GiD zNm#a(!?`G1w{sp=!TIhp__~v#`Yq=>>u-})gl3L(+XmxROH03S)@x3*VFJQ8PbPXD zQg7?#PhP5X_az!qW~dts=%L%6w>!DYPs5DDJfB8i z;GRO|RyQitp7^aMrhU;uY>lX#4FA-Pjnl^_z1509i>=w%b(OGYOUc|aNSN~GDVS7x zlxlQ0|L1-~)uX3{txh558w2S&SHFtnm#jYuB_kJE$wKeA1vTX7(J~YV{7g5kD%^B2 zGe|MpE?kV*%J^DrKb$~EvfoQBLqxxwUiCd;Mr@6qEvii^c%(+qLJ|dev4gUv#@9}Y zjQw7R2?&%~rz0(?H`AZVbvOF++vybv1PD0kh+9Qx(*dZwl|2X$wl;yR=mo^~!QdYE;uS-)#4sUpA5OHWp%qRPwoIVQGvvO^kcbgZ4 zMZ9<>NH8rwb#!QMYC-+vuw5zd+P=MB`fF{F_gao9F{o})!1|uC-m&k8SKHfIP5;iW z{G$E&w-x*UbNR}(_XUBK{7XOCf9*JJuv68>CyQ=vKVKj7Fn8*cr*>X9t;%OD*c?Cj z%Bh$Brv{xEbR+k0d?iQlJ9GSvz7U^+2X?ovrk{EI@C-j(=scHg*q)X2K)SJH^lx70 zZb#lfaq^p}4G(wMtvwiN$at9aaOAQHzie@AZGYeNVfN)RqfLiyY@IG!-5K}u6~Bm? zrQHjixNFOvT+WRA^C!d#8-n9)?$$j;OkqF*@rk>0W1F_cZ+zrlB6m-Es@j_&IFNld zV~zQ9r`{8HYD{-rw0iQ*y_HG%$-8Hr_&&yJ^s(<2sbg0C^?b!IXSwgw5@wE!*;a4b zKE7_k+#@Fn+@Tt(=Dr-Qjjd&w?MO)7IHcma_s>V#EUK0z%ft4_!Y56RO4CKAKkv?+ zup+myKz=L!`jU@Hn~|N1345*_6YlWo;nfcXKjtl(W10Tke@(Hem)BPJZ-lLzuS{AR zB~1DI{-?=(vwqU%pYNV?`b|-nIsndSngS;(Oe(+G(WdC= z?TNl35APeY{N3N5Zaho|J0IBD?Y{s1hDQL%2K9=HZMa>7LW;MUM)|flCVrF=qZ#kQ=tCOuE zmAbk}67?iBiuL%pAh#=-a!vFeT+61eWF-bZRUl|sTJzg!dHd}Kp2bU^Sqnys`xxdf zU5mQLyUYyCGdEr2vCz%ZO{E@OnYv)v`K9m0=BTlLH@D^a#dltQ^lIPr6DzAze2hN)eI#gSM2@Hia|0ws4wReK zere%X0dDSpe*(1CWmKqbmg^WxBZ>ohs#`XW9rt$p-2t;ce4jSOvgq6j*<2q3&vMMs zuI3FME5fJ@DU*&3+?{%ZYuOA86i>Pr?Te_3b>0CpH^e|(>|C2cnf09kN`sGi7=-{R z28C5tS|V@owXC21Jh{%?W`$k;bUL-?WQlr0I5GxvWXDwQ_bu6A2YOkB?$A ziMa)$y?tGf(p}@8uj|TZaMgPRQ`F5wjP9l`pTv#f4O%cQv-G=#ih`qC)Dr{-{I>4A z+%cuNw=4});>)6XO(QJ17jRXmm!mYudtnBNsFUQ`5NLYoL(8$M|B?6&m63?Mq7&wU zK>`N@iPtDm&NP9Ix$7?Ezr>BPZS{5AJ%Shop0dM% z6RNM*QmX=996j?X^FZK(`cWU2M5(=e5ES(29wS_89+8#Xf;lgdV)Zz(?D0n2d(7ps zP(Gpor2NR8N-_;);#Y22__hMyY(%ttM)BTORy^Fik=7EIKx$f}dgCA; z<7Zl7Wl$c&SW>qLS-L}0$2o;42fpN7-!EXk^A)X(K>wzIT+x0FRd40wEg=C2;v*bt zI%YAtLP7>6iU?(te`Ib%j<%gk$pvKB^na-lDcq&iFsCSjgmM!;`T?tc_F=4g=y z^Rhskh~*{eH)Ju%_92;7bY|Mg8)pO}1NaY^sn;wJ~bdmqe~uWIqw8~1g2@wBHm zRaLgbB@@PCmS+uflbU@sy<_2uW8c?@72O=;wCm4=uNMwUEEUft|Hpdew6H~?WXQ6E2iG6V9z@hv0};eBYvj8k59Ia-CDRT zVYo$TOp@oOi8Tkb-)%bRw`sh@`4+~C@Jvid+H<42yAAWaot@g`rrfhg(ApX~9~k0sA@no@N!z4Q4~D;L+rDW4Yf+28%~)Th=ZQ^8<{ec_OE>#wAa zrX@wQ-@a|UW1oEgw0Yap%EF&4tS_zTZq7@O>Iho@L)PvQ+#lq|j* z!|&c(IWQwPsxhkK`Qo+f$4&feW8L0=sLai`QzBx{Tv~kn!jyuLaZjoZPg#ETpW-RI zYOCrjMxktDxmt!MHSC}6+e>@aCikwLC4Z7I9nZvN_uvYqCh8zAmuU7pUm)!3;9q-C zcy*XzVaBNS3;&_+hgCM!M_`cV{gC?N+f||3O8Kge)=93FolD9B+fSAs=_)uqzvPEq z|4@rk$4_+5_-WRMt2>Jd=5C*`#O}d|H^)_5rzD+>)r$XKG^^!j;kkRWI8Xg*Qd*Xz zH*H_fIeGhX?12wIXLL+mzdf+{-4}{U^N+VmmJNA3(bw`*{EGMG>(4ClDZaa*C(g%r zd)eS{b@?^_=Z(h<+Y3tEd}{WzK5`7mY}oZW-6DA946_$+#~tbWsz&XBrg`o?A8yn( zUA){7e)-d-x?<=2zKu771_=GSwtR8eC4S5okFGpvZnPfVo!{a3(7)L1>d~`n61yKx z+1PCvd-g@r;Ol4G3u>QKZo5{Om%rEa zcZ~~g+4q{I*<lMw%cFXN9DEPjA6iC>rsx1?j*Bs2?vki{FIaB-A`R~NguO>Kr zO7nb$3i{9&83*p(M+VP4@q76s(_7okvrh&Z)t`$zHSohL zx%8X8*OILEEIK2r5N`G$V=2>yWGs?6uJOt0xxMxMsdrDT3xy@E4?FKj z!q!Zd`CGMmK4F~?`-f7^+4S@Wh#j5E95%TWwl(z)D5qk+Rh4fT^JY(LK-U6;_xppR zo+N*}t!d4kS1rL&9n8igDkmTafjMO?Gx5l~3SV*^yCmSQW@nFo z@IOg9kE11J(R(>74ur&>Z8`MXx&`5Ze|42Dpu0}~UVw~Z{^;1E zTAr)Sg`aTI-{?kNQAXg?2yls|$*ws+&y8w$sn|03F-5Y zQ`O)BJ(QeM3Vc=S7abU{=Ewgo!}{`1YMY6WvjBDsW?#)VPWN=IC4dp%X_T;h)KrSS zSXaCCOw{3vPUX`S6hCMl?sw49)w&RGv+NfW{df0rz{T=q;E&T*K>V}(q~#*BFN6eB zlZ^omTHi1g?@#a#4Nw8Y2qFSnhn&egE7KR53@Wu>0tTcJ=r0--i9j&xAcRGtIa>4+ z;M1>=o9ig~@-&&T+uA?kBF%r9$sq*-_#g%lhLV|yqe*Zdd61qB%xWYkfCf#eP>zeA zzNIVvkV29{3Jl#}3_yPmf`DlDmPYF|h$29W22E;E4g!RTYLS2A zj@e`x`yYq}NWK6e47nDx((vt;u!jUm#H0^L?hw}+hWrp$gH{u6>Z>{X#SC}!21RW_ z?l9a*f3&O+;m(tL%;)HS!U`Gq9hj}8{-MtKDmc$3H=+>4i%6IZwL{4}>g7c)fl0|a zin(CFV&S-q6rM3#&9dUT53CCyST9IiH65ez4rU%GBAW&e*d=|O!y&hTq=5MBI_R7v zWDnD=O^vdoVkik|$rk%cmXs+bU|WBI8cN=#sXZ{Tj`w9XU#t(INKA!YrYG+CWIG{Q zKmpVu+7m5B2n+FGweJDHoxB0&eu)rma#ZSO?1BCOjqD7A!p<*xcYbw#=i-Y04Cv** z_YSR44z%;gq4^YgH)-To z*!au|ECD-*UjENJnhXJ?_h0rz5}cA%pnG-LT4F8fz!jtUNJ$eqxwPlBAYKf^{wKX! zK@^~)tq3 z#>*Dae`PgUUKe~v@`YAvA;ObFkeMZ$t5}M-VC;zWjjr^~S&D7GT57w;`g%v`>yw3h zz9~#z-1+N}c?rTWA8u*JgA1?jB`+E|qFQ~j)h};JS#|cfHdB{}Ne@=p4p)smHvC!O z)0eqiVdy~8Re8k8MQy9t9~N<+Ex#Nqop5k$a&c_9P1o`0b+-yigD?3j)#WlW7j65ohSBazXT1}Q z8dDnfxN~Od_CJFY>SFqkuKVcwxb8Rhi@vSM3MlV47*&^5eR}#SLG7K;D7;(zalz!? z3HJc{Ogww6c6a>#=Ib%z&Yg>0IOe`2=f_7C4Ve#zf%05HR3Z!WZBwe!=JoZYy*NFi zhP`}_+0+51I+4httdOy5qH!&{q|8=uUM$ZG>1ntdj?Nh=Rj#p@=;YxWO5-%Mx;%&+pgB#U@2%*b z5uFC)Qwi-*ML5UHf4y#bDXLVqS1sdR-XgUew>CmkyDj-bF~kOl}IsPS^4vE$BPfAl>PF{A9*j)znqycqV-+oOANz51PKoo>kR z?P7-0JeDReu`c}VzSDf(L`i(qMV@uubJ(6Ms%+Mk*z0vAzZlmSwCjHJW2;mKZ(RG3 z13vFDZEH2p$T3dv+OjwTw;ZCAP>5aN#>7gaYzQe1D-Db@tENqot>aRn>b-Joo81^K z3bVF2w`1!)u!MwphyXu zhRiX17179gk%T)O6u}FCBDSb_wg1$Pp}YM5_4c3XC~I%@sKUEmhdHw1rzaPV#-|fb z3=dm3rtT1m09Nm>-l-{s^oBHC;(%Nr>R-Y-OqWGWhrwscj4hzHF4IxM+4wCu9}W2v zrYRD%v`ZsA1`!bu!76!1&xR3c!T({<^xuitP4cHGtpgwOKR|`F2ImtdjBs&=biF4b z#u(<)oqSOdINhsGsC`xq=#tKoUx5=PcG(F_MV!113Oy+_KuYvQQ!3MHg$tC}`MXtD zvil6+9S3H~jKz%dJ#12}ni^3FN0;q6)fVE1gY5f9f7o8XI_=y0PKD>nZN9{H8L)=& z10aQG!rBtEZR;jr%;p+pGtoo=mjvDuUVx*k2FmdRYcpMDj3-gosrT_fFM4nG8QPGU z#`K!gcTVp$rx4m~6uF(|=*tb4?ygqW(EPql-R|0D>Z>Z~S^Rihy^{?fy{EG2I|eew zB3q(ny}cGe&67DxBtBrCiFDc+pgO?9Ovf01_N@8k8wi8y3nOA?fD6P6gji z12@BJ02I@Ks!1)l!*FiPkKpd9%WZHU={wy|w$ZP~{^b0@P381l-bHzNk!iqiP&kAH z%Ki7DU#U=bwox8K6Lc$8g>GXmENn28+bZy$dUy~z7eHzfm-e0mq6+qXOugIpeBF-^ zx1LI_UHK2y{?MQ|BzcNm!>4C|2fdCi`@|_u*tDHfvAZ(K8(2}`c`)hXy|rvHgxGSs_x%7Bgs0#?fbxR%2hxs$ogffA%Z zz$WL^RNU5F!N6*S3WWK^Tl*Mg$v9GYZz;e7@!6y*!3QuKR*fUhVTvB(u<>_{&fPle z^|}Fk8KwzCCGnWepuVnKsF-7_tNY!raMoYb6}!Q>q1V?vI_@KAfIg*itQGlzHYuc_ zfw@|~y_Ju-+Uqo$YfxoKM{*;%Kej`V(`DtKmQxL`5O;4Rm*jEyp>8;hz2|TxCg*?{*f`UBhs?4MAn|sf}Z~f`LF<`8K=#etIEcV8xtZ{?jzsrzsqEn= z)MGRW%DbEY`eE93?O#1*4}5Z&Vgr@pT41rv?~kuGkN5hWxzN1D^Yp!i(_Es~_vKE~ z{xakG+~U~k?qEZ3ut`Brixt5KzinPIYOdp_^v=9a-pvVL7R)GG^E9P)zk8_ItjX>j z%8L(Hl_1z*Lxt)IUB==_`NZ>XiBGh8NX_467!46ls4S8Q&6>x>+^hT-wVj$~v(5q>d6>tnSWV z$7W243(7ZVN1Wmfcmw52q2GB?LMd!32LXC^uc7o@Y?FV zo}SDmr={Nox@O`$iegY<5-4#ZDJHM!Nu-VmjeU^qODM#v8Mb+-k-{_zx)+eXjllrY z`H|v8A#T}=ECRg)kW(TNpYKZ=a#Yyy5lwu5+*flm0Xfw+7+req8= zPBG3*A^jS$tew;&*mm`P$i z5TRrZaaia8u#qL@*#+mloI6};6kU`t+cu9}JBfDr1lJ+FcL}^(>5XzE+${aQH!{YC z%r%2B&j^CU{v;s@clo#)8amM_s`QCcb)NoGrijalqrs-=H}C)TKC&&Qvwce=sIL#_ zEUhUPp}a}P4}(4D3vy%%2iav8fuUPgrj1!0)Pk$`lIvo(>=jc=E2#P6LLc_-%>9R2 z_mKI+y^YICep~e+^xfaT9U2~asm)fldwo-bx}?v_&!?`cq0}_1i21aJ)8VhezCw)e z>*tGj78aO|efWi1DGEYb5$6-DLO%#HF+qFDLs(LhA0J78Boza@s~w{tBvPy~@^=ms z*%i3`SxE$|5Q!h0*}C;7{FMU)PH1?+ki>s*MSoC#Dp_+xw-*X(+&vRNKdELYEV-8r z%0oxbW8r|I4JM9%|MA8D$+iSoC5OX<@Ns~m15jCGop%)~PcGcJ!sW9!mIs~B23(S8 zNW(4}2dPfv@Rq}65w?_=4WKv zwao57elN^LFgth1@$4VgJUD!(m0}yj7%ge$E?4_z4qLlOc=^)wz732C2ajLEgUwoK`yY0ljFBX11vOnIKv*&(n3h~@-75FF3^TZ_nUWVg0?$ z9iM1mU=rU2-86rDT(=p@f-W&*px!NW(>k^$=2NTxJx1WZ$Tn?|WSwgb zwf?(38(L(1INI4&lp-iiNx9fZF1X&rck!Jc*fe--w)q4gk z6{y_0PIX>NJWcfgUj#V5D8E z@j*ERy@-kD!|mA7FN2^7Iz&5k0N4NLv~kuGVUQNWlMmY-X%LrV9F}ob%Vgp)Il!G;~#X3zfH79-?Px2UCxrT6@pl(4Y zn)p`1oUarGNpUt2WSBzt^mQmH_++8v)&PeHpNyysvA2basclXH8^BB=N^x`$mbnm9 z4QRojaUHcxSIUm28@!+UyRnzz=2ndbcV~+<8Tq~rdVFS#_4s3PM)9^rInCNI>GOqM zuGh5_uLJKy3UN&r=NwGF4xE*Ak2F7)J6t0i_q>x2>2A5`pHI_ee%fw8Dt z(G&NZ#tq^PWOIiS1C3LutGC+dhz78cAa)|y6IGi-vP{l+H$Cm(eF^(-w+w^Dw@AlP zQ@{GIZ$$6Qfpz2_KQ35!TD#wB9dvrOj*FIcpYf46#~wXJS!OHT)dO1a&Bmb6L_u+! zumI%PA?Pb-BC%i!y_YE)CrQ*S9je;x@^$C$C$l#jI9z#gA@7}cD-}~vVSgde#Bwx8 zqk=U$&>Jil==XE;PCh5hv7wS@-i$WgAhmev@`+H<~SeDMD_PO1S8k;>ETmrDEEkB3);p!e))^y9pI0Ez9C_ zr1rwV1AB^EYG?j5Up);}dKD|0XB^;utG!z?P^DbHT(*%bqoVCK5liy9S}|OQLAY4a zu>8QPpPwE0>BcvQ26YHcx28sQo#XxV%~k7`{L16Kb@IaCmi-FjnKxH|UAEOU())?8 z-!&06R(SMD!`mA4zF@o@e>~NDW&Mj>|E>{O?LSRGrGphf-El%~G$jVxxU%k(@;hpP=j zK)9m{Y5Ag!1Npy3%~hDxmtPE^#+3WQgc3tWqjY`T^RKUi%k1}cbf>xF8^c2 zOX0I1T*38&DO?R@x{;2z^bp*eji^Py?z7V$LNBs~33WvBI{!v-G-$_nqX8)i+4?Pz zKC~mQgM4%Pp@Buz0=F7{4oW}&=3k#rdk}KzJ`&KN#EC*FN{YzH2_o(IQMluOHHX>8 z-NmozlC43GubMwwg@{B>j#mngDNoi=wZu>J0jpF3$_M6yYLS6$G|YnJ&)A(+TseF3 zsaM}b3X3#Cy4IKCtVfBGW-H^V{j$J`30X*uIfHMj(KLu7KCOv zZYcPYQSou;&;~uSWH#DeN+*mBLYD}zqXB5iK^B3==nf>fCBF3E~l@4|Ed}&J}@|lZh7R7jW7F&wVa+G{dy zTD>qZds#>W&z!W{VAmHiaVy1-vzGYeyumg6C}60^0?$JPO6AWn?hdz8AW#{% zu~wJ*wK6g@1)Nj=@Is_(gXKuIL>W{m74zNc9fAFnlys^Dzp&RYcWT zRpdtX&L5!?;=7|O12d}MTv?y|;24dH@D#ZZQ@i5b1*q`93EX zB2E(D(Dri{lpH4dK@OvUz$G&gPSIgZZqOzSpD0!WPgRXNWnG+LPFb?XT=dfbo~L0f zCCeC$L;5%j8Xcv5CRz+OIZ)L_36jfQ93xP4F5zLv9ICG47^nf%Uq*~NuwYTDQTP!2Zp=GBe+_3xUW zzqx)VUURVC&+f$4JH6YUt;c!Xd4rdc{Dv(JA$J%e+#JOutOEcamjh`XsT~0ZS5(OOyx%5sz zJxhqq;Cnx)D^Z9UH`rq%a}xXRJ5ZMD0nb&)qCfxzgbyhNIgc*BK@)y>HZoj>on8*_ zPIDf}dG-ktLee|71RrFSeF}HsnauzBSU}s1 zS@8=8&iL)vB3<)gKi(HVADlS2dcvt4Q+oGqx??wEOzyjUlwuSo4c4XjPB>e7>-F1V zH)o0&7?p}G-plz>L4``VN3VGqn8w^#TpUrMRls^mHixD@^_rh5FLK^KD;3!wlBF8+ zwk=1LB$CF#yj)`;`ur+5q9GugiyLkh)DjxiDeB}8U-Y$(s+G?hBe%YDJLA_CZ|~l^ zR9X_e4fOeXH~-%MU=GsA@o%%f`%2<}*7e)ICH!R=th;mm#*p7mtU7at^KOx!nZR${ zlhvY|uPRu7q-;HUY=)L`$Xcwfs4O}9W!*dH7qwDLKUnPn!^kO9wr#Jx%Nlz5xAWOr z6jX)^WiY%TALn0L#ieeAqPF^os2X&I5_o%%7bfje(rUg1r22Nlg~j=I1=CNtrsL4c zIKKF=pYMY4MY9CwGqvoP>+$ba{JNx5Igk@R-_bWsa(P3>6#n2Z-2dbNyyHO9kW2&S zhT%m*QtSc!5M~-QBWxS;nUB&3oWyDq>i}{{@8k4V1c;fKFISS-<8X9%YuZs0cQoJR z?Z`F4z0wcit0;HNkV~s>HD`bdg#E_*(66G69^Tk!JT49z5k$qKy~e_%2j%sf&d(;4 z{y*S!8hj6%jw1ASmEdb5H641ACjc!8UKYcy(E$Jg&d&jAzZ1gNB^J;0b7(;PBY6q= zbNVIpC&7Xfs)Sf?bkIQw0=t}~Ny)V__c!kZJyy=L;`0V@MUM+@tR>PNJ4ro^Eyp7t z2Wgbn0BdB-*RIz=Z^z&px2Ry!3S0|aF^y#`V%*@LEfbn69vt$b#u{aWYqi(w!lwE~ z7suV|=`y=#v_;~`$X%Z;?Z~{$H}_Y!K!KEQ5ZM|*IZRg|JQUFd&VLSatz9+UmHp)5#{k5$hx;}_ zT99u9E=_})XIi>N+_HX7Hz;m8cA;f0{X#O*`2pyVcxp0fI_uCtNe(Hx|1nEugt<4l zqG+D^I3ycMP8R_dyWGw7eohPWhHxOLz9*Nue}R-=)VeT2N6D2|rqG0I-VCm#eo#cr z1dU|s!e6v;Y!w>X+0x?o?BOanI+lW-SxxQ{At4!$;Iw$Qj^ZroXhpvOGEFp=A)l0l_~wf_B}S(*6UuVR zP?vaW%gnof|Ma)jyTjfOH)2A?gCWKtB}kAiL}_qFc-6zdOHTjLSGGX8WXoRFmc0ON zSXp}C@!3^~Y&mS^GPG9~V}sHOMNpx7C}}%m-USRvIAU>%;>!5Zl{ivpUF;8kx{^#5 zA2}`sfRG}d`v@wjyhaKAnKE*|H9@keXxv5T8ORwVK{<1$%*cXE(I7>Qx(PmYc17Xa z;#1e!@65P7dD5#RI`@6;ZBeIO(ESWZThD|FI`V>!@RaTHUQ*hSXhJu%trm%*(jbI4hG)4SL(&rQW0tZmjGndpa{; zTJwu{LTcu|;&5s;5Q~h8V`YO3eka#bV*j_nt}QQ1qI}p&*8w}W~GKS%?fpC8`ai=mLaCj;wxFwAFg_ZAInt3<9B+Owxb{rHR98`Ag z*Q__Wr$PUaY3%$7pQ=OhZbIF}OseMNWX=lZZ?|D$zWSgNTv-6cxcf0p?6TeOjFc8y(#ct*eHojxZSy<#$*jd z^AE=eo@rl1P)5bB9b5c&qZ6c-8GPvX(iI`kVoDWzxbn-J^Pp^w=~{4P#h9kQ?-@8F z)a@$OMp);g`-`eaqY_?krDB_3$DJEB_#f(4hM(qiuW3?*l6lnntn2f&u1@|{?gL2! ziWT41*|lHW>r~UJvI)7k{ZF^m9%8dwYDj~87H3CxBtWB_5?6`VEX$8C4DW5Y8|vg8 z*l_8+0nc>N^FhV!_hyCjB<-&|E?)Y}Ltx;ew$A5V<5C)AiO7N4LEH#2qnvACBy!hP z>CY{+E$Z@_1H;f&gJAW@Gqi#GH_xR1HJ+t^{rQhca7c1oaC)#WdW43T8W3lWhk=i( zd{zeO$015YR`jzUbRwW&`1rHab1QcXcfJ(je8-v{3yCg%m(!dk&x8SoFNAKPKcr=$ zAnd+@e})*Z*iE72?3l0TvxQ!6o$RO*W+=vFn0DXYY34H)HGG)fL#Gq`NpT5!7&F^hQ&T8pM z@4Z5SjHh=m!Rhb&!tg1Pvc(2ZP(#_42{vRC&u4x9o(94v|;EELQMd4tt7w@xny z%_88CvxHtu+LjV~O5bV%MaVAr{11fBIdsZ)u9)0-kQC_mNm5zpQbGOpHP6OrjfPtzDLm?I>pam_%jA_3?UjRtp~=5%pKjX;RQUg6ey z2Y^tgDb`)FT@6$s;n3DK8QjS9Bu^4l-p z*DbKC@~o^aWIolcR>>p6lfcN6%!x=;gF{Bs#3F&=&A^<=4Y@UXaPaR9APEc3)m`8K z1+m&;C21L;H5C3<5R#4bpbQ7VDS|Oa$_PtBQv_hrswf9b<#NOV zLRqu{h|Mqu2x3<15*N0g;^q;~AIOyU#E3&_+6^{Yth5@;X3WmoFH-ay2IvK_yWozw zD+!UilQhhPDLGlO=Ii63t^voL<7U~7P9mz)M5JwhEq=S#x$z3&3S{jy{XH0DcX^+TbgjOioW$mmRWl-tY}FyC{%oP zXC%oKVeJCVp}yfbQSQne8Ue*Bnx$EHVab-mrgpvc!RY6YQpy0Fa+xv57xaz#Y8JXv zAxUsU<)&mx4TOls=b%Q0Bu5j5Pwvr}ikSBdvh9v;)gD^3apJs2bpxVbh$U$Nzgd-k ztm2jM=9&1`-bXLAQtNpQNkYOdcPxlx(ARU5b*qyg#Kn>Z9cA63qAOT; zIKKxa$fTppZCIM4TM}iXPB*9;N)F1GCz{BjjWeod{JLro?>a6kOlw8JEt}$n?rZMO zkMC#*pUeBgE@N6`_eGAT?beMigUpYl&y1H(PZjpvr<`|+jQS?#tQ0XgFN;6smuW|B zZ_{8hLtG{QapYHvUhI`%yT8?J(+MmuwYNg?yd|?R_0pGRxiyQ417MqScR&%3wh za{{N~uvu^~Ao&=PB|jE2_;zmGvIi+F>UF`D(shqs`Su12W}%v&=)SU~U$Kf}|5B+8 z!MHak!q7UJTR@6VCMTF8gi__MK04^Q+ZwNpK{vS66>(oCM=@vPYK6O zZLq!_O?`>!(?1Y*kh}SRA1MfY=%5V+O0a$SEe`2WTJXRp_OCy5gI$MvBUX)mf}CT- z3&da29+ZQ-tbg-=6XM1o*6vXd@>N;jZ~pz*Ftj=%RqZ&G1Tyu@aQ+XuivR`wD_U>* z$T_1QdZXCyw?JFbE{?c65~slt!r{`PcK@H_WwxJ9A{|ZlzYhpH;uY~%^4Ivv`mZaL z`QKxjjxu#uxhoBClI}>NQg9$Ruv1J&4aUmQ7a8Fg;Kr#9g?I;_ID!zv1+L)8%N;q; zIWSZ3wWmZE=5u~e>w%nU%U2l5s01nN$NTMIk`|#V$BA$KgNVwK7qwui(~i8kabT|f z){he|sYO!z%&`;0XL^g$I#l zRMUM0NdB148{?MHAvr_xx#S-AeojBtAg6(XUf_!kbm+uH%XotFop`&66qTrJ5G3%u zn9?B_x{F032>`{0gEt*#T)$JjcZ(LBqA1bJZit48$f>E{-J_|6hy@Oq4(evughzZk zrxd1%H#?LcjVnBuZY-k=oL~GfrQrd6qvx^C<7tE=v~m?R7ui!}cM?bi=_^Z$VjDR{ z65X_$!<{0rSD=>z&n$OX@-xFWt0AD*P!C$!?hPVy-Z-1ZedIWq)2+Ab*# z%sJhV8}x6Mo>TzRR|_2tGUZ8DWYZ+h1~M9G9)M;Ahq=@tE~-_67#t|*oPcPxL8M>9 zUXBD7doQO>QilH84%4_OnxDsA38|7(AmL_0IRPXTxj|yaqi@k)fN?%61qB17bjBMy z#=$!MBLXF?z1kR4UP#Zyy<$Srh;INL!^fGdu!&zC{+-IZrx3h?-mzuL2IDwO2Z{FU zkBAYb#^Akd#>x2f+~W}$d@+`CC)N{pbH&C1!09`SGQ71KhMW9!!~5**JoCY5xrZL` z(;8H&F;gdZl6ihRE^k3Ia!VjvgJ=7vXC2SG()Qr6AHJm}Yh}Af-VKs)3-a~LY`TWm zGWVg%Ou}6*quj%%cwY1tPn5zOFFD1YxE~f!q+72kP4?*88aJ)+FQqXRnmH~t=W%g^ zdR<6Sdlj5*ZG1eKODeKEw%W@UVHmMnpUbCsm9DjH1bjD+#fS0-3CSQqWO)<)u9FmC zqTk!&HRy{6rOCJqG8eWF=$&X7-;1=`h~=;?RI&(;F+`TMt>g+pWjTtge8zXj1uc%fXD~baWBy?Adk|Nm zcc84wSIbvY;& z3}~=BUGh!S>n%aPo~OW={zkLCHTM-M`QHa&k^d!zX?sh4i*@b? zqik}FA;I^E)ou99|MKx1)EuoAl1K6-9m%w5S_Q>8 z;2TI4f-_<`i?OXj1H-?m)3m>DM*CKzBh_OCP8=Vg73mP+d@u8NkpPm$HLxnpQnSos zajy3^jn2#N5OApNwP6Yq0<>AC*dOcT<$&{NUZgKBwr|Aj?)H{1%dr+^<2nUA1* zLh6-38o4PLdS6t9#o)Xt2hiF?68+Fo?q{-%lkEV5HLhMoSo%9On&kar_RYforIp!E^fdRE3SP`;XWOGaN7*2s# zR1Mx@YMf%>#_1^^;ha=0zpQVX>MErISfzlFQ#k85Y-}N+%o+IBSn`NWEz4$!%nC;l ztrNfk5~Ubj27i8&$Xy4O&z#8V5_($6(xjs&?6Z&D4)ryVmJvZgreSpOPoilO2MQI& zc5_c(*jpR|tO_zYjQA-U`LkpZKOyRNEY*FTXG{IXu@uu~I8SVo@ndDLG_r7zKaj8x}K!qIU3FQ@_9tg(#f5| zibk|p2x}6| zVDPApz}daQhahyA>=2l2R`6wf=M0gt{ZaKm{*+a(aSsYQp13Jnj*iz9EG}w~JfEYW z0(2MDPx6!l%r7lyxa_*6Mtrl+%B6&4RKQ83C2cE({zgYFt@bu&q7S&l=)WRUQ)f1* zi(xC9Y087p9{+vx!_NO)dBHe6xbum|YGh_Bc5eqN0@7+SmE z|6Tvf)Da#Qu7N)C#NUhi2MT)a(V`o&~9=fq3i!xTpu0p5H})6 z(id7hZE&fVm%m}QF$s8a%?66Oimk7ou5LflatKabDn={_Sc3#c!&@zpg_CbJp;&ac zxb|SeWq-pHk)bA#D&q5|;A>L3OWT0s9p@wIV3bE(hi0`@JRu<#7XnPsqfth}C#Ir6 zjP-?LhpCoU?qSl(9V1tG!HF6334X_#K%_$jCFW@F8A^>+V*&S}t|gH_Sq0k0^+$T- zDXgJB9G4lwBN`CzF@(4h+Q-Y~h)4SUBW=qMCL-|W8KI1;oHUw4#*xo1M{gFHKXH{i z`Q|7pV9r^Pt=BMU5dSs*`~LVG^k2Zs2krFrBNJpo!|0_Zf7QRpG+ZJf8x3h_k4A`T zVoINGoXEM7tb1XT$DB@XcNi2z1F_+V`v2dIARVTXFFzfI+;jr6PEQnSHRfmO)k@4i>1M6Qq;^M z`4(7*u5VzoVa&492x%(w7gkXo9umJ1IW1(N$=ECF07vYzDi7Hlau;#89FUC#*Nt}z z<;Oy(u;OFhRcys)^NOE0e5{G~Rk$D-jD6sO?%tdL`ZdNN&j}eqXcwYhAd5)D2_hNG z1q}>kiFW`Js+cZd;m{?%ieBzsh9qAsFhG-PbI$mvrwDqy2iFG1e{c+-EbP4lApL3l zgnD@F33*hBS%c6vqOez zE^lqu1~so*Qg#7--4#m!yPfkDpK#D3FfTd)38CF*`CYzR>opj zrl8#%mwrtIawsJzUURK=g6?qiPS;lc*5jQ;8N~no;5V}}y= z3Nd|7-fX7Nfkhtq69s5WW#KUX*KjHV0&OZx2yUf24}l1`OejOG)^mxc3<`RDFAfSk z&-sYa>n6g@iqE!aT{T0tin5)Ns6p|O0rQ|bd4)JrwbuF5RUz`6fWy{)E@&$-n22Yrnky$2)4-b@3udV#66)5g=Q{@_| zt||>uyYpk-2{23|?-(Sx1`3ASz7UYabY3M^EkBw!sOwVb_Z$u)0raj!5YFHa4E48S zGd8JNONIM&RHtmGcRHt2y{Q@^&N`+l zE?jI4jg%0}OR@z0mqh=cqzUlVN!t^`j8aOXV#GDTX%GkoLr3%lSW6q&`3!Kbh#b*w zhPX#5f&$X}fDJ{ps9N6+aOe)xq6cBZ*{h?<9w{lu*IG;u#wlf&PbT^)j*mSt56fi; zUv<+{$>0Xmh%t!$G6IT%ZK>vQ%`mN?@fc&Z(!e9HienU-GEO>bAi(vpI018Yx-Hb; z@H7H;)_&8_gGpm9;>$VG<3Mz%#-v0BRa7*iQS06_I8dB(d4}_}%p%6*C z;Zos;Bv{7(yBcieY}(?`#4GVbh(ECuB*G^5ofNDL0Y1etwU8xJ!)};P5hJuD5=Y`R zu;uhJD%>p+@(TS>TCZlx1fakPM<|jx!8(gXNkTHb0zK_Xiv#Qh+GhT%FCmm5iLqEQ z{g(TXn*Jzw63U9`naYWYg~K767w;_AGXS`6M=I9T=gk|_mw}T9bMinLP_#of6 zfe+5cSVX`W!dVd2Dha$sP9(Vjy?TYfK5`VugWO(m6%<~SB{|T{qlp11(x48h)cLl> zicy=-OsRL9na8vv+oLY9K}QF2Nw80Ihi6av2$Ven39$o@I!ixFmS#2pik*w%5HFa=2}3)rF{GKdCu zGyCX83Cy!i`ZjMhYRpf$U$R|%V2=CZ zTRroI+SETv)1%57GdU_aDn7anpH~j}Cb2eig6+bDH+`Bbb&I;T30~jsIee~siiOyi z%n42O$TuHT9{4qzQD`?|?d7rvjB~J&rA{!dD|+$&=z8~n7}Gay{F$jKBF71Zbu2U4 ztQd(F6I*IJs41-2T^riQZjn}YEsB=!nhmK@njA(o9awfTDOz$G$IaFhyE-_8kfn9n z)<*mLT=z4Bec#{v$LOGW=6UY>xe+eVZ;# zT^Mb2=@i!fkpUAiR`@w@@4h|M|IAj01Qgmu_b42<^E!W}wP)x=Qu}XcIHvp6k(uUmL>sxLYSY6s6=e$%)R3agz z33%Q@(_tegj@(|Hka7Kb!E%@sC@HXkpMG*B0%xfNIU&vS&_SCl0>(YXq-Y0;*j6Hg@egb2=iQ{yX1#e}+w zC3VxszVrQYrK8Z4g!CGf zi?f3cA49==b(zqK>_$nE1)zyCg$GIHL2ZkPWdoRIAY8yY%&`w3PoY|c<41b&#Fp?q zBUJFj0&Pq;V(=(^1E5H)bGC7)uR<&V@0{tS&BlZhV3fhYaS<6)j(l4oRhAp&osr$3 z;c`+NnFFC#gd|{ojXubEyua1067dBajGsLg0R_>;aiNX$=asMwM~;O`9L&QMeY`N} z)B@DV8j>LEEGP>rmQF6cM}(!~Hvq7;d*SVpV0WabyL1)vINXg;JNF?FZFeZgoE z(F0pvd5uIZ17Iv(SQxYwR1`9f5>l>zNb8Z@bVGnYU>`f|hKKXm%-fxnD0HO2g6%?)}(0 z%~Tq+BJuPuCA-y+Di&WG*mr5qmH~hNCYv}g%KyyuY}3K*iQg2@KKe=eqg4(&`n|g= zD?Zs&Vl_n+@?P=CnzhLT7qkyTH*F7Q72qFqNQS9I=fHZsGCUL&09#q~g-#Wp3kpdM zTX!8Y9+iaFBb`Fx{G2jd!UX81XW+7<2WQGmycfjIp(F58+|!$ES(pL~p*-UOE&?t1 zE>L}lt7*9<>!ND+1b#hl+a>*~m_KRWQ?+>;40pnKo5EBakIT2Vdc!}G2u z&nKt+_0JU#Rj1J-t|ZjmucZ#r;-t|qp5W3cf?#T3`dYDU^LX#31D}3)!-@ORNBlD$ zK%vCBh|Ym3)r86c1%yO07FXS2)2s?X6YkMIUeR@jwaA7?auEmNfqxGe2{tj)mb?Brb^E7$Z&>1E_38_L&aJ}#<1x!KzH>Cj=$ZSNJ&SiI^X z7o)R1XQx}#GT_YCjs^Y8rnaJ?!u-mlr@mePG_4z8l-oCLC)R#fg$FK-Y5}F^hLD&q zN|tk9eAZOdZ$ojHpmA2^4RackoZ`K0k_n?ojjI(A@HURup&?A3j+3_4*nM<11~OiY z)EwqfNKPz71JJYYFK|Dck) zH|3={x?TVL;lu|n=&_Sbd8T2j>t0SM#DMXf{B_qIxmVS4EaG#^QLw@#bH=SfQO7wq~uJH@^; zhaV0N@8N&nI1&z~)Q=AOd|3OP{6^KFH>gwve!&27rjz>`o*2DEnhWX_3idZy@sGQ_ z^fO*!i>e)6VwKmRJ|5+d(m%KN5Dd^nHYLdLyEe}N6IVLHxw%QHwwBl1MZnQSRp|WHq_=4 zFNfvKMS`M0dNMmX7*%!1_JeSG6(2KdwZLvlpf#l^ z5A304y)(&%h4oLmfRbUMFEM|^8MDa~Dy<}X8H(?SzN^4=vN(RgHV&e5bbMKh^31NH zelhToaWUNLmVqFc1D!^ys@~H!y0wjcr$BFg;La>0x#VoYWbkyq=z@MR2>c!{z|iZs z;FK*DC}s1KAsZupjX|UTeq}SZY!YHFy<^0&lM>QWJ5g8}8MsV0x(CR+=+Eb;R3E@T zqPGi-j#Q@zZk(Q|TY^29W$d4nN-I7?kM|?rs_4X~6ZUmbVD*@h0X-^BqTE(Q@puNP zqt684!4(zise;*ezNj1o!zDxz%u%bjE@Y!5G{**ENihNfTdJ0xp~glS!G5a)T4$ZS zRXp+*@{ciVy0bD(m4!LsVESGwO)zYT!m!Q}uXQQiJGvu~ zqctz#U1Rn$1ha{2yj066S1l^@4YHEuqelT9JofSp;?Hgj=)h;`b?MP-3GTjJ1w8>uN#(tCPz>aSk)AVm0SM!I%YQ(eim zq_Ha>Nd(EVSB7ozNW&D>?!G=|P-y9a>Ln37(879N`w*lK{dw*A&>a!`YG$;$WDV9V zIl365AmQMLY=KZ)5BZ#e<)VI77;0$Jf(U?LQe@*%Jq~%IIopjMN#e*U-M%VG5q&FS6zkKwb&`x^#y+04(X6UAQ^OdwKpA*is5_=>Qd2BqYQCh`zP>|Fm zObES4?PLIFB9OK`!HYAABuT!k4>@UXu#ujH2tS_wV{XX`xU&qEbX5Ux|Ehcj65`Kw z264xUJk`+!X%gXh=4j%Hq=x2Ts9E%S0N_?wn;PNVXu4{VL7Ze2biBY5+#&o-cR3eX zKC03`$}QlhM|mg)S)jAlsXwN-V52!`uuwz|qI0%+M^?FLV7ZJ|e`u5IP zI0cOjKvQL+?JN|%*mYMS1pIIVJX^v;#HMl7xdJ6hnWTdXp)sHh3|N0=I52nFM5TZ= z2DqC9uw)rv6G-o+YY8SX(B_T80pzVF3jku{Hj>#&F+^J`!-^O!Kx;`sJv+9KHEWC6rd9SQ!M(xFQ&nBqmC9FSnrp|GB_bVClw(tF} z&bt)EO%0}IK%|j0@baON0!V9++>*A-!B%$mYmnDEp4wM2wt zgUQ!rjHv`q&eT3ntBS^_+My$nQYx{k8ovIqr>|-WGHNNc8I=}vs$e`;0WoOd==JuR=c8d2Tt2kZ>WQqA0^bv} z<43GA95}aNFZvhQB8UV=v>Zjd7sO{cP=J8%XdO2 zv!hRF6)2)28Ubyn8XFem1z*u6$Y#6TUYJZ4&U-QqO3cW;?ysF3t;6-c(pgQL-#1z~ zK6tECi1fa^i*N1PmAfZOZ>|NI8N4hsIL`|82k9b3gX4sVUnqLOXF7JbZ!;*A1eXUTJGcMaXBfV16`u^p6G&fkc{!S&daAh1YqkZ zs8lIATLJhE%j$iu?y@E>Bo6Q*IYH1}@A0sX{%6X#wJy`c-CQ4Dj4zpR_UIJ!3PO}b zWux-5GcJQfh>&~J`H@aEyrc;LJhxKVl()WW_Lu9+g}GR)mj@3uz5JgdcH$y!Qji4Y zf?{Q&!+7K0XX-R9g1e7{IXEqe z27{na7?upZ192<}>gJfru*y-BB4Wh&MEHaB5e$>w7~^m0DWsn9&lHdM#}SMfao`Zs zG2;=bk!VN&t6^sVN;iuepcN&LqgN6bH6cg^vPgNGUeH=NX*n8sAcD6>#f5J!oj$zT zb$rBJG29NIHr6Q=Vi}Jyf(G0GIcg{{-ydXzz(b|s-r=aEtaw(tWaNwn zdDqmJHNV-$Hh&%VJbxTIGcBMo<{Zk~F>ey41VqDDMq40~h&6UL;;_vDW4hSwkKkg& znA9#3Y6M48Z!JY_2~m^Z_b-bUC8|?5%XOl~=v1WmIGSrj{+E$gODIs07zf&+ll@J? zAPqXkfH)-V0F_D2wncrQ0P~wPpbMJFF<^?NDFZgXn1W|KY{9XhmT=^Yealol)+k8> z7-GL-TC6+V8kmPLg~{q59hJ~fV-ih#KL!?yJ^LLc?DD=d)`-@H{UlKMgPMQ>$I6pO zMcUX}pR*mYnM2^Nu$8R1jEoS=dBO(ZlNmvQb!G9r!$fbGcW?5+5qBt4lf470Xp<5` z#s;_$cQ)%2b3T|-WAQ~H%p=cgRgg2c+%0a0R1llHXi52%vhlZGhEMvYQ{tiPro;0d zTaA0#8gX!b+t~*Z9~bXTJ@BZme8;*YTxC}77w^XGa6Me4-@M?1FN3z-a_ES{1@xv? zknKYMkg#Y3LzlYw^bh!N+GHNA0pu$vM13e<5)?{fYN!uqlgZK;(6W;1B(}k?$Lu<^ zAmN0331v!c1=9XEw= zAZieW4v-^DSUo18_Sb{;&-7cAE|Pr*;%dGuENYTpEZ)58=sgrsu%kw%Amo@5I+>=& z#0+mmjW`z^Z`JDr=W>3io4W9l(?fmT zz3qwP*L~W1$Ag&ClU)R{X3jt@uRDl)0}kiVnPFH|T+oYb~O8RzYSs5ZNwq@va$&pIC%NPP;d6k;^F6uG36 zQQ}z;nT8&|L*2KR?RHJLg~#d_7KEG{nI<1nE=)#7qF@xVPLXR;{rE|>e9XW}e^gq3 z6C|s-bT;M#bX~}G*^Zpw4*g^A!H@!n;q- zkz?aGn|9ycE7=T?^nU6TB{i0~FGL>9LbR>yrur(+OPeJ2^~h)l>H|&@8|$*+x?7(H zf4PvWc)Id>Z1KC9q67PLa&GnMuNtzc?U%yR+gj>ffCx7qI|9hycu?&u^ntstR5coV zH0+u_&$=*I6?1uj*#6gVgO|Od*_VG{ncgiP(n6bN z^tmh#&7Kc7!1YP&ppg`IIGs@s0CH>}CPRK_%qSM{OZ6$4JA>QGj+sgcUlm5)mv z=ML6XqG@+1e5Mg-Xa|QqLIhzkfGw~RM`mF23?w+Egtr}KhTD-F9alZsArVwht}OL; z42ZG5^>;kFThGSfUSr&P&|}udU^pR2Ho)mT1?TAI1~fWOL%oU^EtX4`u0M6)-IVgh zV}q{cg(n&z?z8&eS+*=8Vc1Xrt_%rw7Rms)4j#sF5#4*0uL$oZFjjN*b`1 zhejjsNvyR;T9p8vg@T*nA58i2l5vQtcX!-6qJIDVjfM+H``0fn)Jpaz40&=QcKSE5 zR=+vOKTUKsyE;U?o~xS`XLKG!k<14$8LgsY8Xj+a235t|>sW?yeTKx=7HnLX%|Oh2 zgn)azx43$mUG}okw`#TWh6nP_MvtB9$tW`x8=#$Cr0DI(YMW5+Yce%rA{o{kB`6kc z#rs!p907A!h?(8=;N)as<`Ti4f{Ore!gv&>0SP)R%+>2G7WVh_KkzVEmLteVUZ1UD zdY8qEKv)cHtI1DO&m9CMKP&+%*OR-?5a6j8P{v zw2J76K2S~;{mFmTa6c=nX*iu4S?Rsfzyb;+xup2WuhTOXhGi#COF{<-7Kw;9kbc0j z@K>XU;3bSCW#TxyJwLVamp0i9n4m@hVUlG0W`OXpV*WR~M++Ebk>E`mwQAK&1KU(G{ zC$5pCT+E(+B<*I$Aw{m9PnGJqyxJh{1j~%OIF7tW+T9A2XQMqc6F!Qg`if9GjoRd3 z6sBPyQ@~~jcb8fPP4hvIXc?C!j`I)LEbp{=s=Yr_RJp3nQ)Rh*gJ3o|d16sg?1G~) zLoOo^9$0U2DGVVY+ADY?Hai9D#Oe{TIR;*;EW&GMH_&myA^XuDr^$A&?ieTivb1fl zdhwRJ7LQd1frIC~nBj#e3g^Onsid=0_t`)E$l%Y7yPHF@1ut!8TQF|lo#c+`N$eJZ+3{&I|&uz0m`ko|eGiADmXxM|Q z_qYm29Ph^pAmGm-@xIs~!%hE9j}UcUpAQLggfB;&F6x}crf5Nx_4T$ZCtJ@(_}d-K z*s%EMS`R#RsB+6kTYAx0Y{Fi!SQ2ht*Z7-RaZ+1f=>mc#Fcv?nPR?3{ujGtTSp~ z)kmYOgc8kf+zAc|^;+S(GBI-H@RnmAPt<&y5!0YTa#AWcX0X?=hQgED1beQFF?*>q zf>ZrV|G4^c-1)roIMEsu(Mr(h3(QaNmQSb0KYQS>Ua{nTw__9gS_@TcumOuz6ycdm zmZB%R0kS5O2BjSwPtV9y2v;yqOu)aWBC*7pqtwLQ&^E#zM@(T0PM}gC$B_$n{&3W* z8%v}UpZ01!ug~=ge+YkzPN|(eDL#-LNFST~s(Iv$q<(7~=Uv@@4NdHiMZJnf&kR!~ z@W|N)C=6#vNV5Yf1zL%I#H`6Be?HS$A7_jrlxoO8I^ZbM#+;nK{=rS@=;QRXw9+d2 zc+rBjji)?J1-m|;YRc7dV3yuEECdLO1O^YteB{sETVF}?DQw2;8En8vb*w8CWT_tK zzb~28gbx}*F0$~L0gb(~ARX`+DjkNP=xtYvfu}RP0D7 zgFg*b8cX8pf4`;Xti#Wy?41_i>hRs@C3`C?MG7fwdRiK1F`mSku513mh)O@C{mhMN zC@T+sR_JiBOuYbh3t7IHS%vM5P%IOpVLVzaR3f6%uhMEixx()YN|t&g1=r$!YC_yC ztL10Qf-00Nf`mvrm@(KE+o&BWuHz-bIaQ%e+u^o6i^9(Ybs)h#0oHV0N^1N+AWlPv29g+Oss-uku=oKf!+j- zPcL`5U7x+SO^}m7CrXzLC00wAhNz>6w3cQ6-u_CP1LgRJ?`64jG{B4zoFNiDTpG)w z(pu7s{TEAW!7BF%vmc>4tn2EtFU)wod2@Mf`_ju!P4CYszgJd%Kj*ihs|J4NTK?sg z73B{;|6pbHvmdUOUzsWIJ>*|5WTK{8=}@~S2Yeo#mp92EVssMOTywee(lO}Rg=M3q zqZf4KT(+?Y@R1RL&}L|IK!u}>JzArWhk8zo&bm>JSx3l*=g_00FNPkzP#M>9V}+T~ zlpuw|Yfr52^2#;Pw<}VQe2{kF<&Tv$D{3|kIgoR3!A#x5KwQng!n3=)g9!bgD#W-p zxn(j9f3m8`oPe;RI*gcOnE`)Xy zNzhCQqX=@;aYh7fJt4?J15KtTxX&~x2&vC1cN}SF>O73xg1Ob#2VgRYwGM%BoTU*& zcVI^A37t(No3Y+u((<(JN798!Ju_Y`RPO&__Nvd)e=GJS!lS;rXdKS1e(1_(1XgTJ z$gKKkL&>r~E3LXLTW-S49S1R5zjkX>+ao++|1Y;v8NRmR@!@0lj^}O8jQ*&61B}}F zxZ_USFCI#5T#fp7RFie(jny z+Z?i+@LfrV>!&J}p%*=xa-g5emuC|XqE#dysN&#euwUHfP~|zyty-Ou7=g^_Tr_0^ z7({S5Gc2qefwBcG1M9)yudv5=&YsK*~taU!$IqdSH(WlaG%{_$B?`eQWLp0 zF!Cs?uEVO}hVoPQ{nLZQhR%|Kd*~FcLpBP$|1<(RX}q7LTS&C7awKC5)B1LT8+|-a z20TZ>E3`MPB{oC=39TwgpZO1=8ZUv#rFIFF9*%Nv8fwTOS&`y!Y{9Sn@1t;Y@!${a zhqVkH*v;1GFWK3-mu5{5i#unP(-uYsCc8-@UP!4B2EiC*HYoc6pk+C9JhNjCVKgHD zgRq7{6TuTp^2ghIAjrYT$9X(s0!-NuEUtxq*7Oa5paS1ixPZM!mN|hZG#tnu^XIcD z5h{-CR6v}Otm-UBjVdx;YmwGbLjl_Jy265DL=^FbE`$oou>0^O8DL-w*~8Es#f(P| zC9e|1+_Np2E%8R_5)6y_^Vs&?t`dP_3wn3NIcLUrup4KY(w0v5=3+{T`H;U+Ujp)mYV4pm+oick#uuXC zYjC=Z!i`EC(50jw>4}#*Vr4`XZZh;1PwpIYCt-j=VgsW@gM5D>Cx*y~^8q(HxF093T@46*rC6*#I)SoBDs!J}AJ zeV+9gREf{O-0B~n@6#Us(P7iGPyX(K8R@q-$v+#q{lWOi9g8X+R74jn*Dt-(@?y5z zwIf`~uwQa?V=8-zB^bwvonB1 z-lb1L9QZ2qMmsEX;)sdm4VPY!Kt^%1eT{hy3q9_Q>3B}+5RRy6KgNze65)TPw0o{W;UhR*1 zBc@)MM_B=F4xa$hPXn%yl%kMFaDmFubOkOIT`)+T1=}CXB#8G14+-l6ix3zBjN`18 zc44iBk{L-oRx`~()SDfOh~VMVqDZeIm@|A2CW31vvPhh=9pS6zZkl)SmubJ=55d`t zJ{7huV#mDsAr)sHHQW=rP6^IC-d0!0;az=X!f4@4pQ}M>Gr#Om@kDprNSLVc zZ7?=PZV)!!j>1M3%&nHzZNktBg#-l$C}W@ds%6DDq4Kr5o?uEwMEB7cvSg)oPh;U+ zAlWWDXSJR8j5_~-b#+IN#s$ebhx!cr(^NSS^}^^4)CZAANjE1+qXtX@C3EvhNgAHI zC6&}iGxs3U(FN|5q$Kqpa0>Pzv%BFtn5`R&qBDE)IKV(%IzbF(Ep!Aq56+ZEj${&i z4qb-#JPa`90P|$Z5$N-FDddZE#eZKoeUK^s4dt|)NmN`%n*R^4RkzxD2wgHGZ^4$6bKd`m`EoE45)lU zGeJYBD5t zVGOgSrDu^;hsmNa19DJfD5M9{+oZy-)zktAwo_AoA8}MF7!xp(q#B`;cWgyTX22Ar zIQPT;0r43ovBUzV0A7oZK?7+bT*s3ir_6DfO=+t;!b3oBS|7jy>;|)KYIX=M?%F^) z_m6#=T3*!5{j4d!JMA3)7Oj7g!a;QE>slUK3%c$9=PQE*oV~@ow-%^lNCenp0>E4! zUavzn;-a+U0%<*^@6ls-oigUq-#>KyY3FX>{k;wG?ZXG$6CFMKe4k&k=ikS_xa{@a zVBZ%z9UaduH+=iF#B}h{|5`rRbvhQRwtms~^JQZ?7TrG5J5==h`H~&W!%>4zDu78J zGXY2p`}e-~(slWoNk_w~`J6r8DAA*J2)3UV3f>GYC$w!9n5m|uE|SI+r^UjgzD74| zJBku;1z=>5eJ{miKPz>@4Z}6bacpOPHM&9y=ZCFse-Nn^7910#-J`KI@Tzf5hQ8XH5V7`r4To zuqh~0ylR%V>^$mE30vT0_2!i)A;(To@Q73`RPojvWbKgBWq~p@l4jJM0hUJ<)5mu1 z{;To$;rr!|CH}5C?Zpl@N&N@;&b#yKS`Bjk8D~i66W@R)9sT!O#gkqyR0{iIN60lC zs8SddP?U?UP=&h&QM)4l?_)1d%dV*j=W{b|h)#V|`Qbr24y=a2$|YTV^9eddPAPd* z{e7>Pii$yE4cF8EP^Kz(EeMu8^yUy4oTR5?BDg3-HxPP3^<|!&0;5dNquBsP+77B< z50|CW+PFlYL;fzON1J&qI32AV8VY3ajTMGV63D*`q9Y<9k`+0-gib53-z;*g9KE9E ziS4g)ho2UHFi54r;obfVsy%=a8K{HgB0}oml#2#jLr#rOBz8hpgGgM4BCRlZS$Qz8 zdu@c{12O~jqX8d`#^trhrvPe0_5ZDs`g-8ZiW}7vK=3k>9$7wYnQ^>fygRcS2deK` zefz+y!J7xBSA=R3v#^1L;>m_$C zp*P#CLu(tJ{F9)Iq^aaS7^Vh3plnkE^%H>zheTs_#&Hc#Jv{So!-8P~z_6d^KZrRN z|9$K0IfF;c+N9v7`uf&B*f<`2>e6l|*Pp99c)09oDC=d=4QWVuAtNi?#{15gdqMqu z%G|{93kV;OIJN{Wttfyj!n5#H5l#+4$Lp5{VrM~A`pPQ|YC?jy;0|CiBLMa{4n80n ziWWCVnvhsyKqkGzfVHJRw15@9LSmtt`0E0z81WFMqHsUF0Z{e0cBJ$2HFr_ zl{az9!Lp7ApA5YJ+-29mJviC{XDVx|2^&ZskZZsK{^pnn?}C_3HKsS_V5#}6Hr|;4 zz4P+|<=FayuYT=6vtN8D;^q`L;S~&>KmJ9@$2fwt@U-i;GOUm@<;yS^2r+LpH#u6L zt7@z1tZ-Kdz(ma5>pY^V%`kT_=jh;?Bb!|kF4Li1L|(z+8PsV{t_oty6nvalY&okp zHRizBgE$hZMlAI}lt3F1h}Z?z5rs|gC81v`JitJqtu>Bvyn-mG3YN4J5cEc^U|IRN z?^_E_nlwwF2X}&=0xv%BPpibY4ScOmoO#trYrck*8v z{?1xtPODF}UrKDv{O33C4?mWER6Bp?A2-WgZ+|y>{U?pPdvh=J3!hB)N86N^T*cOs68;B6pX(#Hq_KCjrwAY zHu1p8J^U%6h7>RkAoFY&$ZR84!ym>InQRy*qFRj2Wr`$MJ?Hh=fDF;Q=$RFBNQT{z z$HNBS1=_h2=@4v-eds0$-P$?zm%6tnLX0wakm`QYSF4Zlus4OqXT>BaQW@R#3>4^vb} z3;u`XYcX<`=Z~sFUfVhSiG|!JKiBBiDr-2C1nggooBT|bqIm`qW8(e%^|GF*z*V3M z6fFm3@Ciic^O~@+xfBIK3!;qFu3ct6s{HU_J~aOAkdAp=@d!KEcc!FSMTTcy(SrGB zZWwBnQzjvstcxH~5%{u3Nwq=}WDddCK8rjbPPh#{B;%*qBy|fbGBiWNiB5~gVufla zsX=gY7z{7wJ_8d=^v?0o(wHB@mk!ZekGTHV!M{UfJoW6 zd{w&unGhI{1+N5oM$BLkM4!vQyA-(#IGE(-t?s1wqipi-dHts?kC7-Z%)awt>MG=Z z5c?RRIrF`BY)OYdZa2BNX1-JGK;dpwW3#pc3}Z{%!!>skR>Zb{C!!@ zm*uNP8NK!tG;|c+x^K%LvQ#Hx9hmdMV1)b`Ssvh#Dne`=^$q^PwH`LDI+R-9KvxaK zwEl=lm*K|M?x>=vdjc$Qd$Jb!;sKC#jN6h>Y?zD=vk9(Y3J?DmwLOSvOaqcrA#xj$ z1=a-;?4<1&@l||D6X@^N{>TZn5{JO8M&kzPL_!Ld_yvaoD-7?!s_^YgQ^^ti4dO5` zC(IB(h|WGa0etsFHB=oSmu?C|2xF60xEl}c;?5C@(LU_Lq`C*vnp1NKizC3k(pv~- zC{hy1ljx!Hq_EX_dE(W9)j{ zmjOr&-4}J}^C72)By6AbDt^qFb(ci0+pqsqTe@@E((q$#_pV(w4T?E?{_x7L3;LPr z#GiliS4lt9gpqyyX|4GO24@_D08^JuE$V~QbK6cmn4wBCKOPPR2qRL0xmw5_+^=U%>;ks=>9_W7S@lc=ZvU+{1 z%2#z5D?8K_m5CH$YlLkpIEhQTENp-AvgMUlaZ~LBg3jj&f{*7{|1|qirIjk0#&uJt zC99--YMB%7lcgd$I9Svs1>7qG08ow!S2rY^3p4HUPm<$6%SH z)=84rnAE?u2!SQY5*_)3zv>PyySVLEG3-pQLU&e( zIAr1f0hWLn{3l8-*;~lQVIDYtU-&QnphJ!j;WO(I3p}H)PZdr0!^GTjM^NrLq@?h4 zz0xven8C->MS1vuu(vgV`Fk8ZGK?(;PQjoG7M~e-K#1}eV}}U;X^uQ&eg1Pt&M4wk z8QP`&6_xG=9gtpxR^BN2+LG5tpWyZ)EE*sP>jUFjabFnTiY4l}p)MjBsego(XzNT% zMteedD!2;M1kV7U4!zJ)(K2}>@cleSl`^8F0_nW=vg!i~P!Kdyk8Yk69bcY8f`&26 z6eNH>@tT6C>%%4=*^4-j-`)JYb?y;LBZ7gvPDW^nwwOIW16lMw3B}+7^10??cc>pF znI*h69~x*S16Kb3uc!GMY-89m!a9fgLg@uMA9?ep>T8S#sIc2-`X09;CASFX1I9}8 zs~DMNw>ZBsQ+E8>_zS;1{;Om8gRH#~7anu}a_c`jmAHS7pW|H&%US7q^x8Ft%=f47 z3SZP3+qu}3bjW2!a^&g#w{-notpX2S^f`QV;Z$9RdzKl-*f2)(g|?PE6;GdfZ9qgZ zvUAOMgFBk*Og({kF=9p!?gmyz6vl1cu8s!Ennhnk@+Cs2KqUWAx?KgbnrI{8TQR4$ zkDg)+SO!jcqbk^uCNhyj&rBQI5`J6A5rX4Dfg0xaG@BJY-q$Il9D2hL2s7Afo<{i%OP-Jxm=P8>sjku~TN~4ZN1{8^d>j#rB9^U~mSEhDQRWzCCGzkmI3 z*2q<*&vv(LQD&FjxTWVh7~@+4)X^25=-b121$=`UM4jI0l{9f7x5MLu^;a`TjkTIE zvADl*&53X{M-cx*jlaALgwk&65XiLtU5}W$r=RT|2mwI46oNRDW9rAgqH?}awG_iU zx>W@u?UxKoPf^2DWTf_|ptXM5;-+&Icuw2|bh zqG}D@9MpS016Lp^8u~%_hTP0=Mmkrw9hHl@6KVy}fetF4VUj|^N)9O^2m}Ixuh3aH z?BqIS-A|{Ar&a)Zc(@P{Psa=&XGlk931(!WXNjyH(?zWgB0>QtcZ8}GX2^JafZ5_9 z%jdtCOQ*00;)I+Iij+;M!)JoEA^+pGf*^C8ogD*xG?X*^yw@=P+7@D$p(#W{HET;i ze(itEUrN~LnOFX7TF$8DD~ooJ>5L<&fxQS#>f>oQ1^+@4EjA)=Mv?(-xv5$t4l#gGn#W=-F&|1%i~x{5;W*H%d_#%!v~fy+^G+Uv|O2C9f-eRfH4LD;CVI5 z8wky&C{4H7mnN!WNE=zU?oP$jfOL6}z=?@Ra(@s1k|+Uk*>G*<=%PcPS*$J1fk^1h zr+{=$AN1;vEUSmWu~+JG_z%heZy!|c5+xy{LtTL^}Q3kCRbfOLBvhr zs9Edj$Mh%68)wG?@*m00Ak+v-dZit~qtV|0uifP~_Rizc>c~5Q>0D?l6n-IthC&q` zq~4I|j_N7F#z8njPRQWuNM*X#{BhA3C{BDcXw1Dn7bpc%@O$4$wT1W5#EG*3p@S@k zl$ytNYrlWkJGSbK_mirxRefJhsF0&b;-WHg%Q;Cz>$C?d69$>%ptT>MzD#*c>tY#lmerZ@PHy z`pt(SNJpL2kmm_|Q?o3OMuIzw!9$tC>Rk)#kkifOYkHKAg5|*>zywpx5V}bV+9e)Z zm6=gi)QLbktR->06zL`0Smo_kwcZMUIQ%{RmKdBUoxufKcYgI|byHe8g-3j>L#%S= z96AF}gv`CN zry0kh;#F7WhyO$AF_PF|5;UW>5u}S^P89%28R8y)V-#1ve` zo8qw=1kwfzk`QV$7(r^>e?A^c?e)*3AqiyJq63w&uUPl@Bel^LgWyGyW9v`u2^k|6 z6+mCq{v!ryb~`?~Qx_;>Ov}ieG$gonNIaLa1f*bdJ!O%Jr7??7fgaOI@oSDwcAZ~Srx%8pnNfkN+Z-I zW@HO{hk-hukp{-THitW&2WnhwMI6{CdUxRTeQoyTXgzkDS4L*!-9|exGgY zdSv33;6MK5#+OdK@z3;tUvKWy407}Rz2sl+DXLWe7WBQ#;4$^g9@~eEf_hegT%{DOZ1H8}vS!EUhvRWtzX%-x42_k=b zX(F>JnI3M*+$!8Q>c!wo8~asK(m)_O%&8;fXhK4UKiNVSw}HN4wh}fQlVG3=tSkEH zjSyT2x{U}hPJG~COv>SVfh)*!!h3p(w^DdnJsGhC;&&EH?RiUyRq4ZNEkZ_KGBM3J zYNiGFp}-*QU=Vr_O&;#`ZSbs(B8SL^9Sx@oFAP0vTNJ^q@%tsHWXaAr(^eR@O?jJ- zE&5oMr4wnVZn=2w>KF5N-U%%5vdJf1byi%hs#+n_$mBxPIE@PxnDl-!VU=$A%PMDC;_- zA$_MQ2XcjKbce=5pZO(Z{LoXW{OIEHGflre=2@|7SlOBacu9f=OZllDGA zd=7WSnhoJ(V=j|ih9yZaTTfnNzu7KY zM_Mrq>9uSoLj?Pk*Sg1bWQ-*-zq$q++&T7UjYx+Q6h+?mVL= z@z$9|t@aVSfBTnvd>3kB(v{NGUq^pZI&n)x%cFIBhPT?9c9jlV)f%V1KY6er{@~}! z9|tdAxj8B+|5@Lz-1DZ~bhMn*puHS3UofRq!xo~bb$8`%`UjnvDIv@J9RJr>VvRsx zlaq%f!1N$du56o$p)&AH1PNmvVN(j}!qF^$Hk61I7;TWbw^yCFJl?3#F0>>pAvBay zL8YK97_76!0}3G3ltMyK7mxv;@rVO7lAcIWRw28xcc()%tN?x*V!SZE$kYiy=?$>rwBMaH{)ileplAHU9)peCW(gTI>C)sX*}L(ZZ;% z*9y9}z<=51?ibv$5M>oga2}74PfO4Hu>6!<==3H?y zMz2waV|If+P=^L0>ng@;agG_{5!#^-Hk@Wi55O^mA_N5@XzQ>;PEgRGeC@FQoPih- z0(Q_n_!X2SV|pyG$$nsf3*{xG5CLHZ@z#_UfY>hleWudzkmMH$?6KiYr~O~ZW=1^T z8mANhvna67tkK{JwPdxWJ(%$?w{g)w_pblbeRoND+{9wj z`VTw`XI*^nPxUwI*(+k+Ek7+ut#<5A>IY>YNYG+Zg}ruN*?hpYuBfsh9d_V4l3jLP*fV{!%=+;9!P{ND4Y+n-8+%G!*gL& z0XnBOq2rE{B?sAy%ZiYt=!Sz4jMZ~j4)rPjUVLHkJb8x)CD*bQ{=gc3d*7_e8>L49 z1_A26M)anN71Vwl2WuFpe2k|cmp~n%w09oaIW*X6>G=8G72RhiI(puJrt9!ndCI8_ zoirCX%93UY_c+Wz*Lxg5K)Jc`IVuLQ=|;B^03pOsNlU?50k?-Uj^_Oc>CSU;)Yauc?J)4tb&0cS5HatOE3btkT^c3nJ{19gIOCc`{{BoVqyV^5~-0 zsJt=oC+Jp7*r7wnkLp(}J}j=wZ)eSJc8ydUfnadweJ7{0iC`R3n8uPA=U9xJkQ zz=fJh>6}eR4BXwtm*1ftvNzR>hr~=pBi8)Y>Q$FN{66+#RJNQOoavH^fzgyP5$CVQ zekhjgd18u0O@Up4XkbAIx9T2}m=mhed2y#Pn0(V_B!eDqK!pK<&TCZCCD_mm^!ptc zrV2vkGqs8pBnKPqVB1U_{72o8JKCfn*w)72mh3CgfQ2*v&YXD6uP8TcIMzDp}n&;dhxfi6xkv7{nc{@ zH0nf+shD{I1Xjcy(R4TL0j)n;ex^AP*9=2;33MRV*?-8o4=;!IjJ!4ca@p;+YN%$o zpXBtR;zY!WJIDJB0-G#Uhw%uGR;jA!Zb`k`-;Kk`#JFprvNBG=wYxl&pB)r*;A^#U z>x!+nK3`t*HSHuBCg`M$0Cz1;2E`M(3K+o1E5eC@Ck_Z>1Urp~3ZRHC5TCqFJUEt= z@2_jdTBbhuC84wUUr?q?t%V_IV`g{oUQn+vOo796M)Be=9ZHRL%z(x)jA#uY2ZNIw zG=64B8D=ctkOHZ10Suq?#16Qg|1=# z|Ee?f4Yo09slT8z9t-1((##F#bH!09S{sx;QsjgwPV{rXz(tIrVP8?|!0Odv=$dV) zwH+ZEL<#@aW5mLQhdMePq#H=D@hpkW8t4ax+XXop5etIE>Z}Hg5(-8@Z!EYR3vN$%xTEW_zB;>RuU$p~Gx=!h}#;~*4O{=wqoF_uDlhLSvfVxgFl&OzfiEGShtGS?2^X(r)F zErGoO-@^nXN)w5|J-3c&a;B#&`ki)=X%qUb%53mkRW0<|^t{XU2IWG<{8L{BmtRv3 zU*Gx3zuYGYE_*)SnYwaeP4eeQ{^gc_w>z_Z@ygHjJ=R6sUC?7?^UD19bAvQ1YR-%z zC)1*HqjB7+Peuf)FrAb952( z2jXM=qEm>Pg;UraWk5h1*`J)GkR`sBea$^v$9E_;2j0OHjB3;4@9zO9$HYVz8$@=X; zJ)p8*8TK9eQO7uYf?_t%!fQ17+47TWDbD#i5Cc>jT`K0PQM0{RWk{O2q(*aN(z-0U zooGrHL+;`txaHEisp3CRMYSxPJ%8r5 zcQ>qULASd6BhscnHa*%qMQ)eXR?}FwwOD2)*WqZ2*8q2?%5bVptdXP?oA2fb1CUSV zNOKGv(SOyGXZfM>4vBlYN(%oV=mS1`4pqCtQZ(@XIxT>K%6kH<*XJ3rZ-hx0&Ze`q zLZ77U_z-tMwUt;nJz06Up6cjmRvd=)V4gSpf1N0gNfqRw;E#8+GjgFXAJR-Wm=u1h zdgbje(8uss)Wo!3w(j~fnSxb_4y|!0fkPfW=^8>Out#tR=tC9gnQyj>kVwv_6hO9} z#k55j@W?=yU|}GH75fFjWckh*HO?Dw1e?}{z_%&h<&ujE03d4pVPrzn#g&^@v-mBaHKKUy{+dN~JV|y=S z(A@!z(`8(;tfzP4U#f5EserSL$tM6|@WiM{w)ix{PIZjahIE2sPNDu?O3u3T~3P zmbzTByg8C{S_rz32rWc)7~7JcwylYhB!s-@j2!V3z!PUwU(%LhgYXnW3j~{Cj{X$w zokL+#+vZd+X#3y&;QWC0qV_GPNBSNkpg&skq z_sc=uYTaKn`>%R9bwTUS`^tdUL?_)~7URtZKgTK@LwzKoLV>GkW!1An4~MqPqZ0lJ z6Fg&v1_7~I^V6oo3gE?&exT?+G+Z>VAPbm+bH*E(h9L_=Z`Ng0BVk}(of55TN|0VgPQvf_UX^b$Df^(sbdV8#!iP&gDx1Dg=m96Q z0$uaCs3d*4n!0zRr+kUNM~C0;1h2fGr$uT*gsOsu6l6_0rQi_CM)pJmr!qQ^kZ{GE zB(gkVP2I8QE)pHrm^tL{B6k|-j1mBDaqjlIBI&BLP1 zFx>Vfs`~1Am|5Tcj^Wu^ucNFEJOZsEdl&>Xs|Q0~MFo-CC3}N0LUNA1fgZK%%{)CK zR=qbJ^`Rr@gw-aS1ww&Tz=z>6*S`w$8F#6(!LEJELhv+<1y{;EnJt8WP7IZLTSDK@%ztm(R3=&wG0|J1Rp>`f>ZsPCSm@5 zs&X3`5)*n*AUcF>5rq`>Uc4QgI~d-nk2nsoK6+d$79A5an}#k#ZO+kDn{vVo{0WBv zjDuIv)NR+Q8w1 zh#kR_ybgXba}7t&N=v_`laB+h0Q#5%GYmJ>UvJ15n$SK%bAfu5OJHp?g^7&*lqzo_ z-sUPVcjKn|m{p3klR_B;?Xn9fz~z~VFe|&s(f9-^2gZ(q(%0yeP6&LiF(}iK`gLC4 zh^iv1pCrfgFz30q3~5wv)C2$g0iZD1k~GI)7!BG1q(cF)>|Jkj9EwFvt7z5CuxhR= z#_hhxA}pjYCXOyHQJ&vWSCo?sT!5oss|+FBU>ifLBX`0k_CY&QPM&Y7l6N3ZdJqDO zz&-?ou!wn(N*EUA(lK&K#RiBWPbbl(0GSr%2^$F+GYcU)hCx3xBX7Zs>RC;r(Q%e*ETR_xBCjv0(YKPa4L)l8sTcyqeKmSsqgIo1*+_<&~9p z|4Dwn?^}O|T-SZq8w)PB?*3s|Yw^NqN5e0-${kITo+Q#{7&hu$XxCev=e)Vf+5-a}Z2N038 z*D#EcJHu=rf)pGI%wpP(-6YLQxX!zUdYl{!T?F?IjvmuG)S4hrS%o0siGqg%_FHZ2&4gHxIQvE&TisJ#IK2w zG>V&{F{sLcKWBYp%G;GfF1i4U#2%g9nqlz=Iz_CcI)EbcO@mEBYLUASe0+1mb`V2A zeDVV}$grjWJT71R@mQ>?%J4MsgwEO}RqGx!c=h)|6e=_&2L$C=U+uflR#qxAb$uMh z<+^M{23us>_MJELfu0x|L4Nn?=UC0fQmp`Cx;oYP1Zx;_k z|2nY}>8IA{ui%90_boH(FYeU)H8w21uy1zh1lOU;nvKCv_R701+1ol(e1R%iLe=)1 z^@bYV_A}|K1q~SZKF;Q^+6wh7yOvr*l_F_u1?qxrQlT(l+hd-VKz2jbMRJo2wS)e0 z+dm)ag_~~bQOL#j=(rmrMx#`j28y;iiE=ewyUKLFQmSCHX%+ZxTmQ^Qk5Syy4I?HX z&Tx>h%M`bv1H$8;55kTb0GfCWf3#4A4kH455FY+TD^hhZ;q zAjI4t1%=G@n-SugZ+ts?G_5JEh6w8)zoX~QHyX3ItG$nhvH-&9NjbtHhVEE z5i%#DzN);LhD7yl%1s%XdC<6Mzl@9FL&4+Fa?%U_sgGwQ&0NK!QVkQB6B6S$F9;6F zKio131p~@q_oEJ%lKUx43k1_ZCUN{3_WOu6oQ2^aYY}n@`-ZN`^dcGfZ$6y9H@^8K z3unUr0agnQ-z><=FEum#8KUFk(*5C-5g6Lg-C3^c>^Tla75vt1RH1JPVK^Y1JuQyR ziJTNI0!CP`)oaN?K>ji^w`6F&Vu@EH1ed0PS#7zZ<*UQcq3;&=cjLyLxiUORmrjo+ zKwdPpR>mS2>ZwJY`H2k{Shr*yfSzVs)Y}C~+08&%7wjLJUvQpU1tkY+Ew(FCzv#kQ z$PilD90theb#es-uks4Qf*6~%hBgbqh(FYGM$XUUU`ddrndilW$ADAbuAIg z&%RvuW8(FHxvM@=A0_S?5OHt4v*h62%ZDdEoc`^mv9Fqohc)bWbbyh@jFK3L67zK( z7T8YH&uDkW#Nw5_c=3s0dCU*O3eYNmc!8=TGmZa+C`Ut95U`e0!>xjLBltHGq0XF3 z`i94Fm?vtqKLyo7G#ESTWRTO!&xOcP(RlKtl?* z!yF{}7gi@f%&+-w4~Xlv7gsjN_{|$|Ex!?TU?T=}cUn!LyH#%#0wz+FPr-(;9DhUD zeSC*L?~cg|^z6iuG`fk`C0VHhiKx;1VQNf8_bq#8dNZ{Xw9nZl8iWF=TIuh3uCV8v zUrUVh}Oq2F8yn$Y!eh;_PX)+e9+ z^YiV`_KwsJo%i!zAW=blkoX@sd{STEkZ+0}P8>{_zn*IoUk8t%Ts%z48<8=_r6ImepAUI`{DOQN>nWDD!+5HLwq53wVqynL+IFK4lo~?6|Nh7dNL|BGwhyRbUH;;?5 zT;uGO?_5T&oE;7*R*931>j+ zSf|stS1uhiElzB0m|9qtmYSuRxqaW){eX4O@B8|_zJH7Yvpvs!U-z|quFrK{3JI6L zlt>3v1g?uvBBjTS64>5Nmqw!_fkPVKE+@6=R&M;?gq?C$xDBLy&mTi+xw$5-C;tPc z@@Wia(g!!ND9U1qzo-_PrBiN@3J}x*8pNM?2;k3|QWxBKP>l-5M_@EE06cA1cX%Tl zQE~f0&nUU#+#5r``9=lQ(w8t3m)ob+;H_lYk3VeXi?p?wn=z1~m|8Dw?8%(AD4 z&401!oZIuTYh+~S+{Cf0&*`k+uEyLqhA#^ACDyCy(LzG07Av7~CaCe0jr zAqoydHJu@NKR7%71fxPJY+;v+H|!jC+w@~cBd;VdT9B1$tsG7}3~ZbBqhs<0pCgIR z2;TX`BNcJhN|r; zqQey9s9F@Ra_w!W^w{#(W$x}ud@Rxkh<#9-B6`ounm6qbkSN>6bqdIct5c;@!2U;O zm1`sFT3&hMq1=x@5S%ap1;{iu20=kt9g*&rt=>~wcB*{GDcOAa`z%5iu>oN?7XTFASI$6U=ZEUh7VigP`&hKsI|jJ0{m z2Byo7u6?>pm^yE*ytlx*ov}D-%sdslh3?k1))Q+JjRS0_a-~#Zs=GDiqz^-MTj!gx zZ*xDGVmRliiSOH#E|8gyjN^z^%as-lZOH`FVpb4BWy0w(a1 zAoi}h7CXAi@V?{R?~dr&7noR+X)#Avh5uyv?#yLJr%$#YU;e?-A9sK1?)lJjte{=X z8dHh_sB<`2Z^m=ulbArreUF{Xei3nJ7qXLjF5SEpXSPX9Iq=lur;d4X-1_O4cbxdg zsasmi%&)!OWm+F`@At1+!h#abc7Tpwy+GRY1p~vLITws{M`eZj*5swx@4LUnwlh^> znKDNh_unYR>_+U*=;|d?O|Ne_utkfgajddbbX=0n=|Pi+l#sQs=WY8|(beJy-S+g% zZ{NsY<}|Dg2J2_%PU}5Rf&|ch5sa*)wA`CNy8OUaONZ|6+bZKyElVf;eayQP-tAYM z`+A}w?!5~MFMt2R;YTNCi~ckCjY;tv-Z^cq{v~_mq3?3TJ8cVUT@RQCc6={q=!KT~ zh(i_~Sc|%Q6FwPs+H~9G&AaN|E$3e75;%A{Bxy-8OgM?+8o}a6*MJC+(Q#FTu}*(> z=>J=D|DnZ^g?uA2D_Ti^^ctEooe%|yQA*q&uD=z*RWCp_XEpizqNx8b59R*Y(O>2t zJyZ1asGOjhOd??M%FvLg_tl(~EIWNZ%$Ydq07CpEr&ZzKjUmDxm(|#th*KW-hn1BB z+~oW#BEQ+OGClI;yu_QTMNLG+X8&B%20u8}M`&fYrYP;wLBHw(A39len*c{#tg`008kc$YmmqUXAGdP3o0|P}7K1A7#ED8bDjXO62u3EFv*jMZA6KD~k3>nuY zwdeZA-zx(}XR`qqQ&92=SpTD-CXRpUEj5?X~`}b4?AE~+QIk+Qg%9HmNE_m#z z-#^*WexU zb9;X_(>KHzY4wN+Q)Ud!j6tEd4~$NqF4v9A*n}P`TYc*v?+%GSFA)^xP~EGnzqs>8 zq0<1WNsN)B8;KmL!-b&1rRQKWoPz#&**BaRe-tdE3;HPbe zsOQU0_iHti7r2`Hqx{RKpX||Z>4Ds?)S+t6o9lBjNN^3WfUgj4nl2Y&={%>%wkfGg z>!qRfW0!lDo3-a{ZqGzdOXh`_*19{s_Sea&kKH@<^M5>j+h%Qe($ITN731En?2VFX znNahn^ynrq_DuTKX^4@oNKxU*uF#JFLUklYCz>7zQAVeQ;84s@j3mju5VxT6u3>YE zR+T-P3q-WQW!*dG=n-Oc{MN&l%hL+uFeWr~Dl@i5(tyGpiGkmY#m-{D8kR_@+4k~`j=v!>-vzD)x z)~Y+8#)Q9jVeo)Qa}Rw!<$KrqYE<7GS|v1kGGgG1m^8$Ir|yLu&W!J7^oX>$7H2lv1#7l*8OeC#S9MQrHrQ{0tz`VBXo#|_) zPV&NofqmX6N_r%Z@c*H>|9^glH4-IkXLts z(w6Hu=pO`p;YsM4hAt}v`3EtQflAQ1P!@w=m44tA94URDC=$jTi57qcNMof$+k#?u zxMEGKZET|Wc=~bkN}b5P2z?WrzbOP~FPoIRI_K=5x;(w(=RrPKw6UnILHHWC;`*7s zqoW$zQtXA$;SnqlR5l{0MlbPfA5_!8Qk7>F+TA{KTmBkP^5r_W+!|mNuvcbXCvg|$ zy99eTB!%fWZp}PB%{~L7an!K>39I&w*Nv7+9Wrn<(0R@V-FFaeh052Jp(%@RR8nF! zn$aK)h3kp`xK-sxVDJ_My8Qjf&iN~=lg!Py7g;=`SUz!lM3j||l}I#|q%#4Aq%uhD zG$@8C^fCZ#N@zM^zy3!##ko}g%`!_3C6IwH_>RYrMV=={gbK$fM2}-)Bcs{=-8V9cvCmBU5 ze{Pk$@wa&<3t;^-Z?3$$d)9gF)AR$sZ#=(wOzU|cxkf`Dpdkkym>@RhYTx z+WGjLym4I*ygYQv6O(q0?;9>Sk||dt(Hu5`*6+nBIkzXzZNF^8sn{nA@7}yKxiZ0R zdb`z;*FKpX`_LE=#65~z)TGo|8H}O6@J-1e)?U{Cj|WCfm(V}|vGHfU?UC~G;ofny zK;F$ekPMLymDwsoH1J$PY6^*xdV+#k?3EG}zFIl|lD$&Rn)n9`3U-P(VKLQl#fD^5 zG)5}T6V0d8rNNjjB%)W-CYAB^VgQ8WhsE7qM*fV(Xr)E)2|`S)UsAX}FWn#M8@9v? z5hsT6O)gr@*h0+gBS$O9du$##4^mMn=~`TbsbA{K#C_|a@X|si6QsLBi#W5<)+yVi zg{CeoMIu5|i@lrbEe8Lpz`>1?UN}G*U8+;@qpNu4AsI9N!;4tXI7~&j6=1Ys{?r7mgj3&N>Z+Uh((fU~r~(=pyTK zk_0>1acA+k|3s#qPQPPzWyY7|63&!X^#(w78j^asBI%w@2ex2$x2bOqhtG<4sF@!{ ztF_qhMPMWC;I-|6KxNN=UjFc8VvC9a-T(36o~@rn-oEy+O#j&j*Z<;K;BK@0UHknf z&I>MfFi-+Tw6&wAqBYe#s-L<|6exmz z6`JkGTI+9@oCdG@bp65z`ZIguE0wGLRm(A_JCeK;N8iqNTvL<(PD+(bvh4`fhR&$*|s{hl9Kv2nne&sr>7 z;_e`ABQ;C6VsC@HLlUZn%(1hzAR}^ffSO&=fO2sLYHo&7rS^ntW-3s%)%u;e9z8dR z?PQGA7Rq32s%8J!rT91*^h%CM+z8C1rTrEM)z+Nl#i~-3ugE?ZIt6hdWPHvtLG2 zIi0C#*D9mT(e}LCrq@4IInbw#rcoVt#3tijXd+)jPoklj6UwSgS)JyeacdP>RZt?nhDbC@uob+jr$UPv}elLVY?VwnY));}L8 zo#iP=wPT^^|2X_5dQm>D@V}=Y-l(4 zttl8{CI7Of)_v>f43}rCm#~GUh_|3I8el(Bu}hf zDH#)Bsm#T%ejr`opgG7 zRTh&06-}lE9kWImeSx%N{URYK8)+`3JxO&_Qd{#`4C0L0<3 zYcUCu)J4^ok_KoqJb?1Ap9q{LvA8{#J_YC{#yGW~TDZ_>(M~MdXrpuhBIm-LYv@0c z=yC=EjJx655oH|1k%?t(A8*K^ekg0yId~<81-ldKV|wm*e4miMG!9218yCelgJ0ua z$)bjYk$LX;Z@%?E?wZyE!-=;YzNh1~$F@&>A?eDX6R$s7y91~sl*v;Vf3u?s54BUl zxYz#n(uXfCUV6v8eji43z31tRubmHRZDf%nU85?c21aRA$UrjLhe_ZOu@vd2d78D8=FmOM$j!VRgkZ*$Sug%#(?T9>OOo!{C8$E>wp zT+q3HyD$ElywW{;*3>huw{HDn(lqU%pzY{v$BFr-x!()!(I&A?M6X?+%-dJe|KShg zwjTNXyWlwbX^JZ2w9EGwyR~#15He-Pa*pFrKh!)c<$!d4-H5f6hL`uV_t}aZRtpeJLSMxaGJxLVM4eqjS{-;Odl;@FL|dm-0OO zDhgBGbBuaH2?8nn8^|!jnL^LyL3oJ^f_qh|hl>KXmSn z^P4uVs2FVD{dCJD?cU+zdwjUGEb1PY_2+(fzwz^P-%TEKT%Z8N=7!c)28iadECC1Y zM!^_;r6&sq&<4^8G$5)%X%*2d@_^5Umn*?Gj`AK=`&hE-WJvo_Xo$dpu2SLj+v#q} z?U){78$gl!*cZ)f+qFW2#x?)qruGi0@6Mdd3{nXZ1;iOKe!*<^sd>i1lKG6NvNqeu zc&Xtc#LY8~Fh_&qe>kPt5yzu_t0JD-=xgS0lVU6>>beQPn<~QPU(={2%#(;dz*~@A zkuJ7g?JGQUac#s_y^l(bb7951h-gxB5^W0F`9cU)hAn8HNYZPhm)< ztPTR=_(mjF&Mi|3#SAN>HC12;I!j>2Y6{+#ffeSO%#J5yypesPhYTzQYA8Mg(IUD; zw|6|l#*?pz6PUvi?6xjBo#9VHXGf#SwE_{%u(P7w`g@3yckZNaIe1Z_*)9n+<2-pwnjQ=Eq8_~7z$O>Men zs}V|cSdooBW1{w(?(7Zw2rvK(8cjl+h^8izcKdqpS%6?&*MLr z-qtqv=#rHO|Nb_OuVGp@Ruo!M7nMWXwYaPDV%~3cPf}cCu&sQ>8aHX;O-D;UuAK1R z!6AP=kk={W-1fL{ZoMTsIc9=$-?ooF-0Q!$|J^;taSWc!3Jr-!exUM)J>}Egp{&Pu zJUF87H&0HQ7CG+e4%dFk76=g}D|AZl`34w?2jB|&N!%#12ZGd5%?`{I(GmGd8ce0I zj_9Ktj7`T}jyj-=(z;A8(_KP*Tv4o?{6-^SY}=#nYi*}|IJJoRjQR6depNkY#w}-R z2_ng6n6)>T*LX&9TvSMTckGn*C>w9c+swj1pbC6qX}}e*VY6bs@Dn`f`2Wy#q*J`& zf`Wc<9^~xET6dr!4$ebeJ*s>~4b~SpFDbsSo;z*qQA7-51T1SjDCQ;HU$Q_+X24Na zo)9TB{9kli!wFOr54KZZ1gm-NMqs~z+%*rrL055FPCt5M+HLCZQ{1yi+rR+Da#V&L7nqyS_g1zZ>%<^gkFt$$wfOv*SdgOlbR);^-)?7w%v40`5JPb@$?qbJ!IR5WIlTsLNMzxLm0Q=L8CU`VAB+`oquu?J zuWLQqUi8xp4UR#JB!L~(?OVi0Xv3*cn*pm>VhqSoUae$(9y1n=C7wAqk%b@gY&Lr) zMsg$0irYJO<$)95{q2z-vKrifS(jf6;3@{X57Xx5WFUMIvV3O8!r`~kSsO1=MJ%fB zQmR)d^2iZ#W=5$euN&qaNB%)B{RS-+$BO^FQ48#M0M)`?O$gj?AOkv&du5yIfbRJTi$n>70aac)j)2WBXtKZLla)3LDk;%q3%){R{>DT0 zJu+ST+%thfMjP_^${W@3r&4MURN6_x7Hn*MZ}Qm0?|0Zj4lrEKM3!CB*3KYe9ddk= z2`9{NpwueNqgx6^6-NwxIgeAKX77`-U<2DkA}Ok|e2j5ORm003%}yh%OhvI9jj>j8|IKNgn~ifa?9hsNTT+XpNQT9W zbS1GUJIWSr-FU6XEUm+(@|i-eoGJKST)gmPRH=o}s!_>pHVJ97$sDXj7<@9xT< zwr9)ZN6tL8M|l)64W-ScKQDyd^N7@&;E^4rMZpaK$F4? zqsSO@+t?rl>xr6<&a|eO7_yq`i?9ezFUFM@5uHJNEIlDc0BsfhRLAnrt6OUx#W%@X zNy+2PWV{XEL#WGE?@B+jH!q6v9=PJ^8CZWRZvs^j=gsxi`4G z;g_!U8qm_Z<+ej-UMTotYY^km?f^m5b(xinJ{fjX@HjNuAhd$52zua>j(MPfBpN_SrF9k!TJSSB1W4jYujn zlvQ~1#$GO~%e~27(`mXOUjj!-0FVbZD{ye5&^1#I#*EV1T9~Qnaq(1jh*C46qCy&I z_uP8&I30o;Nrn)lAZI{*Q|C7?0@BA;2*|9A)yTB8`CBmt$`_Wh1Gc51!~WlDJ5LMI zR$_N>=DfW-caG^a@6CVxKH&Ttd7nKQw)MsC_m^JEzx>HBE&ttO+ZM;{u{5A~@{>yw zcUSKEw!+!>?ONBzH})6;eG)PJ4d(J~+(h^nsYg&0T?AH(yi$$b(LtymV z){E%`Bu1h=d*DeE4!y_DSyq5L2hM!v9W`I zDD7;r9ZB>G3Tu-}f+?)9z?YR6-QAa-+9hWhd5AB4*`x99Tsx!#rlU<7Xlr)*;5CxJ zW+tmPm0ohb$gXDc(@w2>A6lSh>NY)9YRad02YA@a@_a)O)WUAHCTS7X zoaXI*2c6igWM-$zyYyi_WbWB6*+=zAs~{Ir(aQ)6Q0*C#X0_&V^Nq^GXx(3L7tGp^ zH8-+fHy5twvP2rGrJYIDLWvM+@>H1crQij2G46xclA5$@jJta&;e-ri8CTVyqdhL&{O}iq-Fh zM5Zjh`4roan8~R{Z7P3CdGvy;dvfgRu&7HUOMK%_@K3|Ud>O^#%>f3bF`BFuwj28B z5?a}yZ?*f%Q|b?kju7iVm6>VA5<#yaNz9}RjjS0h;Q3ur%LMK{URgIwi@LMUyUD)& z@iXhIeth7={^HH)Aq6fC_X*n<;g?8LEh<7)`&N2~vT$NW?{WR?aZQqLE^&7zBXjD; z^=G)8el*4K3Y1w0y^UQ#JuDdJd4B&X7W#t`mupnkSYhpdI&|vr(d=!<_$)vfeYe;# zrLdH-l5;D$bj)^~9J*|EtW*W4+D|NzvQ0#Nx>X7Da4Za-;r5upNr#tQyP);uAV0GD zZ1#hShs%+{yP!nFzi_K40fs_6sDCecEFx(tF{iros|-vvn!18URcYCOk7;*m3E02F zuKGdC;#&BIG|CFNmLe#D=cR6i0aje)M9NeQ`-pQ-C0a{mo>QD!NzYw zqI?E8qf&B(!%xa0;>0qFp7`#7ii9)68svpHuaAj~4-@#Lf} zOA86=uha;arc4S$>V%8J5y{bvX49;&j+~lAf2(^-JUtgZcI)wZ7k(W!>e{N0D>@Y4 zwfeX8C;u|=x_1BMqaR=Gxo*UVZB9@Bq`LE>qHf<^edg-4FEer?j*JbQozV5VmidbP zEsx6zh%R2bxX-GFAg285O|Sj6eEvg@8dJ_gf3)wBy1@*hiddpQwbF%yAaVq zD#xhyrL@|o^-CA$eKOO_aUxuycQ8t*XFJ;6R=O_582p+^z4-P)+ZwEzD5R$XH1wy( zC8OJo=+vY;hHPR=vulPcMiW%2EV?S}xqADmb3}yg1mY1FwIF+|4w~FzHf6q_3r(`c zN_b3Q>R>3)@kVsykJaNTrL_xSwnf)SE-zK+9*wB4Mvv#`ZEF=L$)ep( z)r77Y$)s{AQIG>)ldWJ9>J@chNY8&-=BzSc(OFvG3iRcOM-@9gLT$ z9g(N{B>ub1VMvZaW0)ZJI4j%p0sUljK-EW+X9dM+e^|08;1P=n|8iKixA(zmty7g z<0~VSJ7xLs)Q8)m#R?6Vp!I##wa6UXS3Jy_DRVE-HdY0@3Z0iKm`H2#Y=t{7OfQ?d zimQJ0KqZ?cCWVVb^C|Zy#A-EZdU;AcFdZDbuwMW$5nEXZLAxcpB&&kS8-3$E8jxBv zub9IU@-^a*YGwY??3Ly2@4`yTc9iO`RB|$Ty%vxdPQC`+UDoc-U9Rm=uTZWxtb|ek z*R`0g!Ol2I_?w6w$~f`Mx>#ce+Bz{tk4ur&%lvji?j1Ji)#i81v^NJs&YUBtY-Ev5 zDUuF;c8%W;oO4j}#U(ZfLX)xQFkjy$wTKY6C=G4H7rL!`R+ZMsod!vy$p|x3N?Dhf z(ZPt#nibp@5Bq7UpWEomne;W`M9B&US3-p=vYq8u8|w$JfSnUO06oQihFDTonT&;V zuV1UqV6;s%0%<8_QrhpiTKL)Q7f2dc(ewm0UQn$FBHSrfK`xY!!jt4<*u@1NlPHdI~fN8y4$YMF}tolAF|Td=|PhF z1dN97S@^u@Z=Rj8JHF_dZRg*Z*!f83;H2bW(+-s&z`8}-q&)7xXF z-Lo`%&9nPA*Khc=?1vn|9x#I9RO`D(_1K;L+ong+*DFK5cax&*=bAZpO^%0NBAHG@ zwHqE$6Rj@H(-^j^(CtClb<59P%N9siTx4&*Wu9>Ew!vys2 z>typx4>~L2HDz2G8WJzShXidW1kq0h?5PU>m$e`H({LLgsB(gYR6TwQXrRS% z3O>P#td#I!@g0WEdD#=|JFl(Z(tTRuE4@yC(t+I<)RO^qATi*2q$tuWd!^Gic}YRd z3JbQY-KLYrp5A2mc3XTupM4U2Gb_6aVTfWFua{vZR-DX@-8XD|qUI4qQSRK3(R|m5 zY4-e6TC1b*b@X-Cy*~~s9u8d!7*;?y;6XRpQ3hcL*517Lt?Y{hPtVMhAVMh#bOS() zh00#3k0~0>vPdAWHB+pc71gwM4DUF18c8mTp}GIzO%28Fu=nZFKcpP;tX7u%>XEkV zOb2+M*>L-=XFnS|vDZ_ZJ~*85apkB^+vpeU>+7PoV`4?5$4*5?t9LVssO7Sckd{t& ze6;WRLvM|lqtR|{dOG1iS`mc#4}z7wv%lBM_P_dN&xF2nUS9PV*PbdvuK^o&=Wi_Y zO`*+Ji+J;{_Z|poP(`5D)|R_#7i(#;x9ofK&I6j`V4K^#Q{K1kjoKW)>&F?_wIhSf zcNd&FQ(62-;g}rF<24KqlYT!mvfb%!=jP^3L?}1{aYNTc2g+i_ z(QEWXifH^tBW{%iMAS}tm?5tKBvjL6WDTx|?lguu-1oVxCpUz&n$p6+rtdYOvbtL} zpj~6Nfqvu~o)kINfv*%7BES=?WnQNcdQCZf0TWv!Ndt(Wu;0$nzk1^tZUz7lZie7) zd1>jS#ZDQ!2Gxd(=JzE^kkB%6VPcT+ACNZi;^^p3UwO8|<-7bH%PWk%v$sKI>)ao$_s{VwWUv@2meNHk zx4;SFx~K#J=Wk8(naH}3N#A8y#NGghc_Wc)suj_xeZO{7ba^v7NFb$Py#yrO+6PtfZvB&26Mzffwl4!2>4I58^dm%kG@5SmNQ zPe*|Eq1VC}i%CHz;yD4f;985jk^Odx_+g`LUS5k3>0Ldry5a|{@i%|O@ZN=laSwKI zt?hZyc@Q6ByQ*v#`Inn&=A?wm;Ct8>0H^nQ$^5pib?pb#X^vlFkLVh(?GSihjv7&f zqIMA$z_+rZH1MS+i`zu^d8Bnw+d%N+%JdT}TBJl(Uc1n#hRQDc)p|O`JwCp4kWJg= zxf1fuYuo-yBrSle(?WPE5N%pyUwJ$9c3;ob{Hnih`;hEeRw~pV+@i~4TtO3 zSikTaZkZJko0)E<<{va8FR`Whl`}OnGd}QZn_x}Sq5^EooKQcAmP2$#3cs@Z*K+9A zyO!SR{CVpqcsviqcPOhgJm2w1TJP`QIlbw7gDZ*U{3A#NYAlQHQEPp|i7JXi$%Ot3 z9!4@J7cavh6IV$Kpdp&Dz=Fk>eE*nuIMgFHdH9N!A2&?=-J`vp6mN|KMg)m-M|&cz zLoWb?Rt!Db&vvri`Q=aVzcg^%MO%G_Gc4_e8tVf$&)P8d_(u+ADaD>@*q$%wdufYVWZMlB!BdU>xsN0WAn1c*7lyV__^EmUY!=p zDWr}_FloE>+x$J9KY45U4_V=3@{c4&+q@^+@0$K=`0{DFTCa4lLc%#Qq|Ww01xA=6 zPNj;%Xl_~+Mna|uaQVa9440KQ3#w%rght44wRC+U<%^l$W>wEC_=S-;gs#NHXz>v> zxET8s#g9V;&!udC_>}u=+#M^-i*hH2Lc*T+Lf>Q(V^!+32=nP`b$k*5rg5DLmfMF<)A}BkJMApAySl=?3@`l-NbkHiK9YcMN6vi&Yw?=n5)G{;_*c)xTYKFWX4{Yv_M{J zQL-fJa23Uu3d<@C!THxZ*w(U`(n$g|5#yBzPcUqwE+0l$2eY{S!bgMix`MFwvAJIUqUp+2tAy zY>Z;4Ro6ui`KZAwiqbr}T}%={Qh+5dsptm4qsdM=7l!~Uah`AF?q^?-#>jl^R2%<@ZQpKXGWbp^<|&aZyninw!hdR zXKA>T8caQCk?>}f?Vf8}+NQR;;BPUact!SWZu}6g8r{x|{am_GMbW|*-M3{?xV5H- zLbh_Hhjg^M$3Hz~YI?W6Clb<13@es-R-;K0LrXSUR33LNsj(I?VR5{G`fx;odJ0O9 zZ`NBwA??&GybC?lQN)uFv7SGwrUrjrj=wIu5a_iKkTQi|A4u(#DyX#XnI3o+0=j^V zf$rip)lwE$MQ|GO(z`b%!QIZ6L{kkaJ5jpAHN0%dnaq%ONC!XGpWE5(?w1zN+wt=59PP1lL}44~ zbFWZLmxrjR8io8)MJF@8L~F92cf45g;>s^(|8vl<4JF0N#S>QT zcx+Jjbp#vDmFqaVW~%h2uAj7vt}&tKzx5Z!2npS1a?wH=iKca5s zhuP%O(3S12>=9B?BOTg)?QM_Nr$WDc1}$+3GP z;~~m77YXIyyF}^Dw>uf)Egw!tNYUEiM#NHWapT3wIT0UB491N|m;I->u@v(mD&^EE#o&pKr=+7Ps?%;QHssb9E$Yldsa(ge+MJzbNXQ-DmrG?;c z4Bn(Gd<2i)&FUrWR^tg#LUaS{N3=fuP2#CA5^j=WnyS&KVo>^t z=66)Dl!K*`N2*JmbcrUm2}tOhGr~zIAxX>#da9u2C~r=;MfXdUyn_+8y~{tMO*&_Z zo^`=WY(QzDjE!Q34L<{G#c4xk*^o)X5sCv|REHqS{3xVjEo=X&Ck(rC`yZ(M89yQQ z3S8}eSH?beBDhC1)48N_F&Po8n=wciH4|74(0CR`r= z{P**}J2tEvI_cffk?0mXPE=#rrOHg|eGmh0|iG^F=3RfXL| z(_UKV#&lrh1ODlw4n&JCby6738Ebs#OADp~OfQ?DP}|9k^gT&_>NG44yhCQj46z-x zrg8_(E|sU2WoKBl%XNWRd-F@u+EVJQt%iA?b;B!3P=}ir+IHBQjlIVe6MoiFxg>Af znTGi zEVqDzD5V0FJ_bk}>OWIJz*7n0Ol(kdMuZxq!!qJtG$M2Jn?#k77FJ7pZ(#Y?f^E>l zvdXY!)yUklsTp_P7dEe1fZQRo@Aizn4DB4I@d!~C*mvc+p%nzKw%_vYk;FxQ^vhjC zltwPUxQSjH;izk6m=@ZHUWhm&nz^sDeWo+mP1+!&kwON_@55-X5W-0JdZL{UCFHiz z>7*k7th5eC9CeShwcP47gg(QZLu$dXVF@JS7Ih}6?WSBGF}7H-sa%q@jbOXQps8dA zC+~k4BRqK{K5D!b)$d-S027eWXm%s}E!;Ll-C!q^#EHG*CqidS)p>AY z-`}ggd3!psMg_MOshVpjsEmEp^PoT8x&*o?06y_@_KIb*vpJb9X*y@~YO%Ar*VL`C zp)dd?(5ZITNGwx9jf12KY6|Nk$7%(<3{H43vRG2v8BTLvauUL} z-c(L%a53_}NAQ-LzJD?ctm(TekG>je-tqFXvfn4%+~@ZRvl}RiGhaRM$-MJjCt7dq z>1_7lu8)1Q=ZvkNm+Xr z>&YE@*L#+*sHX%-e0I%qJ$wI62<{y93QyVy3y6dD%oczpWjQT$vKZ3Ox zW$j9v2u$2DXcPA-duEYvcA_JDz6=gZ!hzthaSAyR^k>tX%Y+=vmz#+q3;a(NT$Dr9 zLgJ6U3ttfh>tuAaFAl`?i_N1)Ow z{k%C|-CaARcNM^z zczF-z-Zy+{T|;C&@-)xmDU2JRThlAAeqGluzukKLb3N3+sNJ{cw8%dEVJG|jQ-9q*=;XMQv}I51u%JZSNXI$o%v~AGE6f*5H}6VGQg{jfTa^e4Nc0sCV+lu7g;4T~4sx)19R8cV zyia6O?eY>>Cz^MyM53)pH#fbuld?>d6oRzvJa4}<#=jw;kKik|yz~QPYIByX8 zS|q_;SAJ4iryA3Qhdw7~0;NTw!SGGcJDcLeg~EL*(0zsl>!hNdOQ1}Y=i3x58uM?gBio{~EdYL(ReeO_AoHuNYIy3qf;doo>LNFkrPONFH5 zrDlBmAx1*4eqaiY5WD4<(J`GmJR1wOF& zHLs9)X9a|RZ3#-v&WY7wKHhH<>YFgJSPTCYS9tb;%EXw;4h$bjj5ian)N7G0J`@J4 zmSQSDV$I7B$>K?u6>_2 zvForyyFPBa{I}AxyN^t|+H6Ajf9if8Uv*Q)>5;vso_5?f@X?hC#~!?Ao+h`xkxmWmGP}cE?o3Iie^rcj&P9tfAko{T493nh_YDQIW~$7b+xV$X5l8 znF#o{3&7J_AJ-)&A%H4SBm}!0EcKg5(4YSiCQc$LA61zz_eXUIv?ic=u?-?(9c8v9 z@uImgzaW@cG(;bZ?(+xt2Ff2@8yq`+T*t^rtNRdck`|INoV-pM@+Q|`q!6}hBfe8o zxZa}kP93!XtV3*hqsvU#mTJD8{F8WFr36yaug2PsbZDunq@^H$l*!|^5M^gY>1Dp@ zT=}Bfa#~#YMyeVD90$!-KdbNj7gglhEIlrg@!jcoZNe&+9`0-XVe8T|mWETZ8whtj z7<{VX#o3QPcE0T`@rluulA1I7unCFH=3byDMzOnlLCa}_4CBjQU!3#e;hEx^#cS%g zmN9uwipSY+??L5!RIq2v>q|+O{hwlHmshOB-;ZKnf;)%7>r?qRDQGZ2O(?fOyH zZtjiUjf$=<_kJ}pUejveZ3^7mohJColC24v*`$2gdaZM@C({_tVex@wQXqo6lf7>V zsKL#zkpPvMIbo_7Ax~2*zsD3~C~qz(1+YdTwh0x|7#OI;l4KsOV?G@5+^Gq~B_8Xs z_w^9A;?FT$NXT?0@@82CC$|N*fwkfX0nf$!DPMXH1s)RNOeOSaZVBP=gp`ubD$Pz2$N}1tc$x`77LPAv2?Ky&& zS70DnM*+#`zUowkJ1rQT)Yfk_hv0ol(we;%Wk)$Cc#*^iChHd}pCII@mUPnr49a)1 z0XLJurYPQ3x0mi(f<$RIDnO*#3|%ml$N<7fbDLMFyJCpD>qe?+XBH9Y|95iKH2IVBzgL4B8KRY4zPc9<|!`ykR#J(p=1 zZj=2Cw*}ftMY}0m4iGoGJ|+Q3bOibMnS>w~ra*zv6G-LQpJ||1H$uRD)BSrz_H_+6 zwuM50R4(7_D71zotl$=MP>qf5w28zR;tW(GWG85!a?W(O3j3ZzMB~$pY6_nhlc70S zMRzzG(WSIuwNC~@td1;n-@df|uC@2K?a-aimfli)5_ogJj6zpjO7-EMH=iDU^^^0Z z1=Ia2ce-x|ZwdMz9<|v_N_k$4_2VPI27=*F067jPidsTy4%m0C`5oSGcNxVNNeb2K z40F@GfFo{l8G;mNw*g{z!dH;gxR3`Y3p}IWe^%mxg4j$8&8})Ol{;X)nio-)7ES5^ zk%4`-m}Oc(dbGX7+FhFz%b)+}``9*aq`B1L7~97u^}rRc_2qP0f>9&_0wk-!!x6}# zYf8Y}Ff#iI5yvd)sB&hP%d1>*qnJ>|YK-ryShc&qPB%yAWdGtYjlJY^M*~!Z_Z+!& zGaZ9crx}8?4yT7n4PaK{;)=-C8(8g7uB}te^ES=fDU->k(K!=~OKTupo*M-VH>`*z z9B>|~=)m!R`KxS#P?QQFyP}>Y-P2?6%BT-T8>ZXzaZ3cfGAl~@FQvGM?_}AGhoOK~aF&Crrwj&v)2^hBHvdBZ-{nfS ze!V!X{cU$19`8Gq<@wjw<=<>LT)c7R+I2H$CjPrYX$q^w@V1w;tm(v-oPv}y_uVvadmrgkdZIu%-QxdzgLkE&$+$m}X0c&$17qz^h39H<=6bvZ zkOAeasy5OUai3`kkLfr$KV|V%Zyz6 zI%Wa_fb%PpOEJNUg4tU^xRvI{FBeX)Tq+=q8Qh)G!}e3#n@p zuT6cPm)QD?4^C)NHq9IlF-J0>;6R3>fu?qcrQ_Pw8>J-lAg?9+8S8| zu@7Qi>)?l?`z0-$T@FA*<8!HIR(0Oy`Wb$sEtJWkDwl?9O?KKuKQ1ES*sL@*&$f@E zGI8?ax;q09i)v?r8{(AYf*4s{WZv}gNWCR$7T2)-`dZidLyCy_?~OK&YL z>Y-`M5S$2wwc{|KVyWcfXiXrdw9y*tm@dBv%%QZI2iNJ;=o*L`EqtQ|{8fIhI0zPh zwXjO~EUE#Fnt4edE!D}zvQ{oEE+Q>(d{XRGor1}+oYxlwqysrrU*y;rBp0}WFaMs(Pt*Xqn`=G zg`S8A&VolPv>ow1{Cc0)?lc~`Hhte~MO>5Y++ayih}x`1;Jj+1n>L(@6-{L~nCA32 zk%Qji@~f171v^+3{)A}2h>~SJMubnEA00SBHq00wH_$pwb4{*W;uV`3BR!E)0%bSn z*Xq7mza&_Z;kH;-)_B+DkRv*?Pm0ZZsn5mn8~r2ylTW3@hF#^MXiKnUek5{~D6^Vj zO;Y5*d_z}KT-f}U2LpbRIu&J+9rJ5(EmAv{=cSifndmyg;`i~LqWk6aj4i)7t%q0i z`V-awNR3@=ch=E$KK4g4B6+2?Cri=0D17qXfKVc)*emRToG?kM+~Pqmk`EgZ6CY8l zd-q#eaO<#M>XH*@vll?Sf(Wo=pWHG z7rX~MW6nzHw-t{t-K^^k<-&7Cn# zdt0|K8kz_9NB^0|;2)nCnyDShmQprcI!+4y4GuoO-D>gh*2p;(&neTG7n-L*Vf%*+eT%%`;b*H}x_S4xyqW*O2FXAT;!~{%D@0-Q9DwQ9mvIKmP@-FoF zNVL27Hi)oF4U5Y^12!lIo^xLdyjCUyVP(rmA!C5z*=+AA^uMZSW-sVXfb&#azJshm z$wOcnF5=nxmdBCsL zx&RO&%@Ehr=?W7Db&R4UuFcTtRKN?tU;_dv0mQ)EYdt!(`nnXuqBh@2S>piIjTR68 zLE6O^)X++SJijWp%ib>C=gid3;GT;)8(l3CylO5%;lHDyfD#R@qQgcXSaK?38mV!A zJ1K4`Fk5MjFrCYr1tT2u+Tt8VdL2bN45*fr{gbs;4yv)V7C{$2{7i#aYWXSuIe33icc)*d&`MwTFVLF zPP30l%Y@5Pvdop}4_p2YecUp`nb|25C8MZE+JDL(0pcxV3XC_7CR%)SmYwziYLO&E zk9SWJV?{M8Tf%nEwp}Zl)fcr3hl4*#TpSeGze#5P{J%0z01H%~VxhP-jZFL?VUio$LD4$VlZ}$G$jqnO9t8Iqv$@LFc4DjV>XuLLC zRb4hFK!RHO{ZLCLCt%dkvR${7X77<0ER;fRJq3ynY4N48uwK5PxB8!A=`; zm7*&HxN!)dq{R)cC-SRySET9bX-=}g3Z{>^>|<+EHvj#lZ5Q1apufDjk@Sc(OM(p` zHPCYRvV`bTac$5W`No6-Oe5bFgSsD?NM2Cvi%=07kv~zA6{5ODYfCb?E4CO2A~lIE4WUvb;~5Gq;A9g( z$$4yf&0|HE|Na6*o>|AP&X|WXFFxGr{8QIfom#yxVRnnF->;u{y!4%aeR=KcTk5yC z*XCT;&Xj$+5oN#p)$7{C4_=>;vTXi+pA0(Q|G~XcFHf5DaTHcyLO%#cELJ-FgY zL^>R9#~nw5{^!0v-w;;drguM^<$rJp_-6;F! zWnIfy{eX$eNRZKvV=}b1c#8 z2^&Vs@6cBjfMb(ha!TjfnB65=FZ_2$tXMRGx@7Bl-{=~{zlG7}Sihx=yd(_^fw?CC^LHBRSTmRJf@e13YtFR#Ga+mbmX618I;V-y|U`XSvWLz3+1e zL+Lp5TyJr^ByHg9`uH~!Z9iU{dhCet3%fo-4KKIk#x)1r=RPV|Il~;x>d9Fuv z@vH4$+xceRLSQ9I>~H|Tsr}aUj~Cwg>e=s@rA8+wFR)NGt?bF>rKQlgCjxThN^%O7 zVjgOQS4?{a>v@qlHjOEf5U_3Yqe@ zG6&5x5){YcKe1+UMOX7zqs|fQEIr|IIQ^<_AWnu+PNZ}sb|8y|GGR*50=HQed6POW zT!u;tPd~wI8f6Bg!KPh%c6t0QSv)$@laVA8sl4W`@Uumr9eBF)((zlz-S^d$Z`bbFoLC!VfShia@WRmoSSBn%qQAw97n6qiUYP;CU))g( zyV9uk@BtGT7tK}j_eO&tUNL$`^P(LaF&!~%oH|hojohdII(fP^Xu{M)Y~-OB{UWsz z(kSh%pIiVQlU=MKPhSxCX$lbL7$2fVxjY07jC^fGkmeC9IsJ!xdV_e@cm6( zi-n76DcH?OarW9kd-pP{C*vxMo!l?aXbqy3@Nu;wh+k&(+t85-g}9wcNrdz4(|hw@+GQ%c%k4 z=bTRUJa|8C5-El|mtKj>;bNtY(z-uo8_NVUFaKr#1X!St)xuhr; zA3Ja*v^Llctu131RrZ5u$D}0FWX%KBR)&Q*N#O0q^pc9Q5MPoFFBFp#Rxgc@T~ucwbA$JsLacfd2F0DXxCWF86}v4J>cx z{N353DjkOZ)7QJlMOml+|2G4JisErJMNQB!M#DUeidi!1qA&u&jE5piGi4cf@eqk^ z>j8ANnlw?z)2KNiN6p%5JfxMD(ZN1!oU%eO#nZ~BuA1vvzt8J^54NArOu}7~|$D44cDHzqFs;dl}buKA4pb?01OH&s#7Yp<_Cg^U1 zEhS0oW$z+^tm8^{^&Cu*WGvfE%V+~*qe9eE@+V(YU9SdkV)lI(N=i^R3J7wIV!Ww( z7wTCTbq6^%K}PT#7xMs=VGl{ef$D)DLMxb*c`v(DCx!RAd->Y?k#Al+aQEd|cbopW z^U+_rr9N-lGW|bmsnPeqsCNhXld>>>TlK1E-rV!=&5ld4HQja&&$#&E(g`=8zS28o zpkl|9Kok#y=%N0`a!V@6z+~&6r|Mqzzh$EF>ol7=hjHNLRgIn3T4H)isCIT!7gbdY zzYyp_j1z}aO|&JhLqVP^gS2fCuTBB}$R)^riC?8^4y1??iLu z`eh8r9)=b~MxgV-z?Coy#2Nm75KGK;7%h32K)JU9F@h56iAD*mRYfxHsjd{KcC2#r z?}{A^`Vmgo#di3k2$gm`TKm`n3gx=~P%6 zed>)fbx(daY09Ejk)M`+m|1t_;?cJU9Dxqm{Njo;FS{Q3rN?INiJI%Xf0?%V=%s{5 zM!xp)nT76v$rOAm7GBdLpVH3F?d$l+YV26t{bJ#q-Rxa5&vDdETCnY#$>ttUzj)=V z<2x@d_@^OcwuPQW5C|jori=~9UN>V3VOOB#-_Z7MB(MF)yn$k^@D`2KbEZ$!ql16n z?}L3@G0vP5Pzj-!)T9=F>OH@FsUbh+SoW<7VNC^8Aqg$i`@YwJ+7}d_&4YcX4Ve!9 zUm-;0tnFc?fFB+RdczjNN}X%=d2zSXn* zB1^+CEIEVj{LpnM1cB8riMKj8>(rR@@loZ0U9#dHuS=WNYyYSJ49Eav1;hLG(%Z}G zb|ijZZVO1SR9HMNT-4EL}XNiG)}bLC2$*Ff>5`Iuo0mI#X1=XTI;4nlt*D3QMsi zgtw7|(&X6enod3@<}-#OvLsii1r@8Rl)lnDF?v%$pMCw^zT8m@pYsLki3+Ejy}O}R zIVe;WcFU1MbMZxo=W3c}a+T862^8uCA!WcXq$Y=?N&Y62O_5xs_KxdLO~JaGrMy4| zR3;(Js@%FhGg593o1`y+rH!eFW2cL%Tw0bxSl96zMTSai?7%TSc0`SzloB*9CBthp z4P&}MGeOC%fwZS0EdiUJZ>Z_NRGDh~(vk7)3~9o4siI63DjMZ72Ox&B<1n}qF>~8j zVGrFGsXvh&2u%0MfOra_LUj4yF+@h=Ao~4WM25}A>?mPu;|a>2go?^GDV5lSbj~Ae zLxmPngWt3eKwI2X$3m!nLSD;Eo|rkYcxLpSaoT%M0#nV)#={UDz~FwbcDPj8$>SgD zxmp&JV>(g>gUNsA$IQVN?c+i}0lx5Sbdtkhqn_Ax7BB)A|NMMQvu3I{inET{sj)Yi zWo;UbG-4GsbYFO{mr;OU8Bz=Fs;b?l`e8HvaJ%MQAkM?ozBg&Bms6xbLG4%_LR+yN zD#SsD)3m%j-z5sH<3ZiXUzjzhFkPY?pU4ABY7jqSShrlNpB%2EMC4qu7{Zf_M0Y0x zCSF=u^8TYKe^?KNd(u`ih4&|Rdu73&{%2N7pVEc=%azR7D?g2;wfh%~#$1-0tXcd&zk_MIt-|af2Yd zWSlC@sl$BGf3;%F&An1z(c47&+`t1;ETth5PpIreZ$F_kDm=z)r{@IfTKM}s*aI0c zZ7e9l>n{(nvd*5CR9e~}CS)HCJG*(@w#-?dN~;23d74;|az!*>% zcSeS{W*2s>yXv6v_Qx9w&KF6C2eN?9C0h8-NVA1nV`$_Pz$sOsWCXnQ?e$k~%`N!0;E`RV7j9y;hdNK#WJ@ySbZM5>yuZquELEYA^flCb1KLtTZGSRPgPWbdGE-9%`i z3&Y)w@Via|x!&xKrmrB=mO=T@q6cqc_)`;G7oyX#gH*|iDR$$!L9e!tRVVq^rtE;zMU(`#>_};?i4jSZZ z#?EVzn_a&Vqp~-DxhuHi%|&5!L{ujwh|MN?RHz~gl$dm7VcKxl9Ii_=&a485-$Q6- zIF-VS(#uDa?jN0-@xj4IPTk)2XZ zLb+BEqSj8Plx71(Y}NXi`D49ob9 z3Yy1VzEje{TN-#@>lG9cI5*-Z8PFI+#(>u%)iYGTVX7!B9RlI<%@Q#;DH)H>jTCvY zyEM`si?1L=LPkhDb9Zk7(ogc14<*S>o~ zn@%73mruD$i8Wg&m{WQ18rXxISuJqTG+~4j_rz`V$tWZJkNM*GaLDd7RzN)x$Z7p=rTM2L5M)9j|q{Rfuul=p2~ zMbCIr&9}{y0za95bJD8g-r@+5rg1SZI=NAS9<~ay)64=C94sDrwFhX%C{x?8oKDH* zxT7XR*L~HH7?xOd?hFa67PiTi!ej<}+W+`cb^i?Q3~q3`@F^Pw=mowp8vR zKgNWK-%y@H>QiVYFJ=0Sr)6X+NKa9u>?Dq9s4FUeuQm3oPmbKlJTf=#w~uF?e}2vL zvr6x4-~4s_eeL}vcYCKzP0#%0*g#M0kybmMlkR+TU$d1@{%mXNvjO`SUW>7J`_v{% z=FbL|A&{%u)vd05Nie??BYy&q(}mMul8!lu`fZK`v~#jAkbW6@tVX(sk9I9xs&6>u__^x}tQT zpQ|B?Aun+=2hgNN%A9yCMIkwN&g`Dat_p2i1=-QkoeFlR)!0twZ5aUSdn@8+DK> zMNf#;rWzin<-jaYCJGJLRPcyPh+JDK0_8kJB7u}e}}Z+nV1c+uPL`avf@ExmZ#-Tl2D zW3PIaZ}m{$Zgsrq?0Sg$prn{q!3H$L>cut3Dzv2Ni0-Iu>ZrI!k9&;;g(oxM3eB=< zY$Xd~F6(y9W>!qMqB_tD-88x>}!Bb%Rh$47=BmMt<`7}?zRz^kd(WyNl^QkpV$J$kgfzDE-u zA%Vs`6cgvVeMOWtVR)o~U;Rdrm||{1nQm)AF_thjj*$g1Bbt4)aDWg+GeK1qs6bMZ zWuom;#gs+vhwJeRBm1tTunDmjUj5~dE-PUTkmWOxIy(W0ed|Dh@rS1zv* zgC*!wMRX}Dtv7RJYI+&?GHccH) zewh{=`DDoSnDm_1^|{wGdeR-42hRi~3eXC%%y`kVTo1vC(abn8!AhA}5+tAFWh=95 zq?Cls!*7;?J5Ff&=l<1wo#xTUi6y|jQupMT9`LGjq#X2A5~YQRX9;%CUc@S!)9T~Bf|uixFjw{ zlj*v*(ExUKnvOYgX(V?nEQeXkNY1XCyvEKpHccU8)N_ztg;GhCX8doju_Ja zeBkA~y&vngVL{xC@9y?~^u~b`BX$RRV_)5DjJRD+X;`@%J;bkZYqds3&2~LhS6toW z_O8gjdgjxZ07$Kdc`J#LWN+G8;l;pGN+nQa!z4dYVWyf@W(JJBLn;+Y{KcjUrd|R! zwQyVs5rXu4!+DgG@~@d+i(N2WNo=vH<@+R@w5t5 z%g&Q5Byw(yV}LDGd(vJ#T-<=^n8F)jJfvPp`x=u_FZ04_Hae5W$WBxu;gCeI$W@|P zMZmrpjbVd43Mx`<7uVHThstRS%F_+u1TacXT%}?47Uo8~yt)6=vf zFKAWX&V8$nW~;WIEJ9fV{Y?2_6L$0Ffv}f1usg7S8u*QVR_QJyAZ0N^oOoh~@2+{T zWu}G6*LFQ+QX|d$lKG6t>_5z*eI(wsW@>e8q zbp}-h=?6R=0qr8)Qz~;vV+*|kD}EmUI}6-cFU?u$G9Y#Xm#-4eE|rk51Z1Ud{ge!Y znb{_pJ)M{wh#{ix`4E-Q%$VZPPGC_24;FP>w>i{uiY7&Uu5|_r+x|@=zj0eIUD|X3 z)>4{Zj>W5xLPD_kHWRMVgE=H_mIu^44y21Bs%QVEGI(P5#S3`pz^l<^BVIemRPCB; zspzMg>gG@rmXbT*&D?SbKA0WAvdpHmz$95^T-3d5+Mu`0U*4&y8ni1gq$!A~95*p< z2tyXh9pCxfJ2J~A(+UPL{B06s;yf6G>TNP7Y1<8MxrW-&7jm%@FZ3Fh@ z*3{xYF}P2|lt?l2RjNnV80K*}h=Mv)5sq|8#%yxrDF{7Ur_6nmudgp{+sd=5V{h<4 zAnVL@BDi%4TbZqo3%rEQYjO#tE2_j>=*1*|=%<>`Cv1$RP01L$c8}e$Y>+4Di4mPI zR`;X-u8lpJ?+&pAlMBuy1Gxzg^npY1Nu2;!1Xv*Z3^HY5N2a6ANqv5}uTA*5q=fW)O9GSnL(|rNGsC74;>()~fWW2ob$ z7_P8fUE`hHRw0KkdZf&oczJ4TdJ)P01?Eu1)hC|V$7|7BlDK*v6#Wfi2UL@4Q&6$| zT)sV2g4BBL{U?4LKDqVei_BDny^w z5P-aj7ZH*jz5LpzpxlBgIhp!JLhfgz;}?Gb;$R#?8t&Fa-N z3Brt$DB$-Z1F4>=+(7PtmULCF&FT$4ozgIV`wyRf|8srsAoJP2pRc|5;*Ih17yb2` zH#mJA6&Zs6A!#G&nVWr6WC)6Dwl**CbBIC1Em!}(OPfeBg_twDVl1nWzwyF{&8Tn7 zLcO0b zPJz%+1qG5|N+T6(a30I_R^h_yg@fKcmo<|On35tX%h^0WLmHCNvVaK^CLqBQ8%r6k zMOC}FChGZO(Bz0D<7nX-zzX&<1`XC*rsi}eYJzr2OFGb}!93Z5kqhZJM$yrSXy$I6 zOOu*5A5<$y%j7{7fjOOLFf9dr=%6Yaa(yokA8cx#nVJ_u#VY(%9*O2cK!jvX!iS)kN0W615A zVpCN{$Mkh;``sBgbwjf6R?5xFYCfq$uK>>|GH71r6GD>&Y1}Wlp+y&h~L6t}YFY4ktN+;{2 zeRTJid%Fgku6*rGn@;m7W*gLxfi4?Rv%t@9Zcm6jwyDEA-imlrAL`eCF@?p>Y#t?R$655!XjuZa?;X`+I}F zeX8MO0}v~c0a>EsZh*!^!Q>D?@+!aGR2e5?DW|L4l`1%{UXGmv1AzO1%zKmdZhF~3sBrT1ho42jtYMZIP&XAn73>s0#AYxCPqia*+8 zWbRw`$J|I6hJ5$49htqL(jRIE@7EYxR_3xU){WDtE&$E+)h%4&{ z@=?etqJ+OtG|ne&V{A8hvcr53vt^rnvY^;7sKTIxfJm>~s~eienTqf7qy_ibXuy?Q z;5Um_i&pAYC;1{I3FjdmlaDM4t>!p$868->kqDF?9LoJl!W*Y%s|5s3`NSWm^A_?p zUoe+Ln&#fix+F^=7h2@v;9ekXC>Nqo=1OukON*3Ibwu%sh z#-iCddvM5KM(nsscN_~5_?BqyLzWGNvnQ+?c1`OQ))Z1(%Rxehyyl~#XrgAC>dn4` zv;aBFqU!&weeQn_JpTTS$!pi&-5xwz_-~S(U&8iLrbP;)o>TJ`<+@hYWY$^R*x5MF z9nv|$Sy)68ng35wE-+|Ak>|M@8ViaMQ-O^c4WXkcc{f7Fg>vmu*x_l=Rgkj_TD7Wt z5PgQ`>Iay6au|MtSWFL8MM*m-O_i9m1_e-YimDCy)Ksya0ubV)X}^-t)d%!mdU^7l zY!gj(A0MCKT7G9B5o*U^|O^ zWe0m7^`f{tDn3w@%@v3n6v-y@jpIx&al-o_0fKVst(VN zKmVJz>FJ0~*PS0^9lVsdqyL+K$nDT%UBc_%t-CpX!E4vI@6J%5%eLzc$Tal%g_cF3 zY=jzXJy4d&=8gelu9x~w16rAiwU%Y;x(#G76$8JTk`S6sY<6~yMRG>Xz6zBKAr_|F zPGA*P7@X5BIdR-n_Zs%k6mZo1c$U|;Q_W?A59BPv;j;!Gpx3-``ZFH0-)WH;ItK))L4=5hi`D_u3 zBsBAtwm;RKhu1(Q0E*g!17k%>i=)mnww-@??QHwU-V4j=_)<-^YcS-?%mx6YB%SF= zy@$$=9)0CdmWl9=D6}SI&n$Ah5p6xl_#tb7t>EA-h#nD}VM%hW zbFbGLbx@2`mG@Xpb#icS?l#DXLW#uonvQ|0X?~?Db^i@LyqN^4LXVlX)3q3Tiuty! zKBrUMu*8|ie24WW8lx%Q1}Yf`>_Df2_!AYgsmQ@K<*9(_mSbU_uod?%1L~`EB`R}9 zHR%7OUCMon8yF&XfI|?&po&I-oscJrkdlZz_>cgv-X%^<0?G&9*3D%|FfALN3=4w> zFfXxQ00p+Fo`eF6+IK4(EnOI^RB)*nX%*qya2_v6G^klpGU{_e{`$>7-g)+hlL0zv zjO)AO&ZP3AwM~;u)zr%aB3?Ecq?_A8>cCyS-~j8MQAA z5S524n!wzG%lysYXzJQ~@75+VZYN=}fyBS*Q5Lx+M?o1*s#3^5p|A@Y&bs=MzsNv* zlXOB}v@$YAe|}T}3I)`PV^G@%RJWLXGJ|7R>L5XlleAXvTjFprJ~x3m zzpt{g@Is0*3^K|0m9Oyy{74!!Mw ze8l#sh38A1UcxU@t4L|!3*hyIqUsfcq@{=zrMfMz4`zog?ln>}1hE+vN`fPqUMxrA z)VD~Ukqvp5gUbGjfu}TJ7FY4#9|!q?)daXjvb%#(^v0wD8UBDmS;(oRU8M&kdSIx` zg&d#q5u^$fhtj4G1tCW0&zJyuPwk#(3;ZIdf~bGRJjZ`7lpJbbc#J*8%bACU#FPD( zOp-bWNUb}RxQ9%_^Sl~llgPPJ93eg%Q$l)CO)@DdMR0WAYFUnxVh)W79NTZj{*5Ju zUWq(27)x4IwXrs{kM1;U(~YkTbAsW<%o`Kam8pKpPzh*S!j-?Vj zxUsZ*z~;xVztt=D}}0rfaearQKEV6n@QLOdZ&HWuzE!7YgPG$k6eW7 zgAS_?tA%rACuyWMY!h)$fcdvt`U~_UMgr4mj0z5}>Nev-(VDBmPShf^z?%xnQ~6CG zEXadPi(RIyxtXPt8Ujlz4ng>xaQdVGbCeZ`MzZC4mAh1#5^jTw6QJ%0(M!Tfc(rU0 zn?>>)w=(r#i$p#QQHA6TG-XX}*zgSD^imT>TXZWiJlHjb)ji8)!-1*FDU)$ zm#B*+yi>^Zcx^hKG&do6j5UKulqd#6zSkO-J> zsmRSAz5$yQXW-NG1-wF~KJCy^zOxu`5szkF&JzuoD)?!7ne}NKr}Vz4NzfuBkLKNKQ?087$j0)>12jtrBC4@f7ob z#h@oG7NZc!Q5Iib&{=^)l|Ml*MOc)N6=6}e34i?1SZt$!0}-9tGN5Qq=|ixL!-osc zcV+ekvEU-95U}$A87i+jZ4cR#Ij`&XC+@C&WYt%L_l&=lVw@jlOWayNLoXtz{RK)R ze1cllcN&NX53~@LP!uEfa&y4VAj+XpZ}P$ONepq8<{%RjQdOe002dwWqzF7~Ny%9- zlt4|Q?P_ePYLAGbwje#lrgVr-z|sz&p*koJClo}G%7O%D%9^by?^4y}B5I^PdnU~j zV|(xBuuCr-e2PUSEZ;5q%o)}&y0Brr8uI+y4D=o za=o;;^9lfu^L|=1dNoc=U78K^4w4&H?h666ZGO#fg19Q!eDn2jil8qg+paqfE1_} zq#m`(%?q!OL!e~_(NOHy3g1Denh6O7hlI|Y{t7T-dX6EZpt#M|6vG^`G$^+lNg<{} zz?g2Vk$^~9N2?`0_pQLQMOP13t^9Q4-BZ>aczG#TZxb+*R2@{wvg-)D*k}1*9@8Mt z=4Xq$bVW@Yc&wHHhhkg-kZ&Y!*}{GxIx?stBOt@FnDXM()mwzjq-fJv#;X%(Py(~D z8wXf^rAS0@8bng99}bWtpKQOBDx>e9t*?`)$z`@eu$z&;Aq2FRkK+~e9YMZ&s*Qns z%v8pkEqadQS6h=9DK17gS)$Z>KN~s=>T}q&j+C&N`a}cnSlkWM)%%GNXxV*}i;yzv z>~iT6w1k|=_97L8lnl0~tk|7ng7{OgV)DzvYbwn_ zPF?hX!5426WBP3$eTn6%*B!DQh)z8WF>SXdBnZNUYr&W^Ro}5obySl~&3rS>l}O~- z(Mx6_=ZFf|xC5_LK>p{<+KuLG$qgxHt^MQQT3c)j-g>3V5EY=9!JF~Kp<|kJ+qV(! zL=uO^kae6cLzp4l(3oC&KOtV3b_lmPC;qa(R7CRz-Biw77$o%qhuRdcdjiF|;ZrFA zwh8%B*bk{j`F+K3RYc-VyJkj4xBtp8(R?Z{_MffpRk!-rbI)ZxJn;LU|NQK|OXt_q0?j2s$c5e|Jzw)7T*IEm)5C3YR)=1N*2@TEfO~d zMss8o=y3=wanxNIx!MK&VKQh#Kd?;Fh89dg$I&J5`N#vS7{bE{2pIEmenGV1PpUIy0ffu2~|)1+I~~>x04=QIDmEB0Iia6wy77Ej$ouSgD7&m|$p z%z4N)l5SIg5ejP4)SN(@BOb^@Z>>h0NK#k=BYlM1`)Ehe4$P2ObOuZD0nq82+EW*?PNX ziAj6SLXBpLMf=s&@8eP;_ej$@Su#rW&D+vir2-|rR>>(vris_ElU%P^=B<3o!0y4{ zi7Sd-wtD>yHgSpQR7(3y@d1g;r7q-Gp14k2k{mKdjV4Bv1dMX|@*%@_(pl^Rq{kw! z!XA6Kz&V*?zswad1)hZo+$NTljW#`#qB%&hv^?uO&__!c>YB|4;ufiTIjyJ~sJRMY za1C6k2!*%$vn$o+LrmS;U75gLwIYdJ7q7ojLW+l-QsIpf{=!aP#zr*fm&<0*CJ7^Q zZ<3o7`)bZt%Paah&B1a8_@FNOgo}^dDuh)I)Go`TByi9QuMtKm)sHlNTnG}ar>iN? zYrRDdg36Wo8>f#DNU4%MWUA+WPpkc9OOk#N_i*{?e%HZ@jl&pu0L%eRvogW@qxi23+7$_Gc;Z_Ud+$W3?Bv8w% zrt&cLhmyOLuKCveyNS~6)aJZ&j_}7VrBvo4|DveDI|`uV!3C8Isr?gg4XWbsI(q~Rz6}91S5l%ZVzx8t^HKs=L{iyEo828J$2^Hg zfhjT?&xTmYZ+eYVtyehE2Rl(%pXgG(Or>fMY_)_@J~Gon9;99bf`MqaE9$+zA!p~q z5clw)$=80luT7tEeuw8W7*H#r`THyHy2WPCsajC`kB@I(D}1!>-J@F%JiFLpsl2!H z#t)U_d`IqUqwZ_D<4-eMC{-2_U$HfAP9EIJ54 zNc$ctf$OF*0OW@f)5tNSLbX92=V?c% zg7oMY%RMay97L;;dOW4!N-}(yCBkeDY>-V>R9bQ}O?zVxITm>4?irlauIb3kKCjNC zx<8u%ylOH5z%2b3UNO{s_=nVyb4$A?m0z{j#T;w1=x-^;KZltU02u;FbM;p%X)^mj zdKC~4<3O%wB0DO5O1Be*0i8$XqiiasFDqfx;1t8@N}Dmt0c%01Sfik@#IS695POOS zTYfvb|ExFo#CwD7XSeov=!?he9A%aeZE*XW86Ca3608D)ZieRSpaccw=3#}4u*n>S z2(I5NBDkVmgs}RPQD>z*xg46zz&=RHgnC5c;Q(<-c&(qdF}yKtm)5c9?2@%N)AB-i zLiWql>jFOh?4tARz&D1a-+beI(uCgEon7}#_sGOz5~d#DwGcn@&P`Pfsjw_iWJ@wG z7Fvz1lL1z2%4#=pL`zI{a05XAco@Cgb^=7@&{(RnE^+mucj7GMT5(_g+u*y+E*vpG zQ}s;RQ{P>QP2FE{d)&FiPbSZ(^{O3A>Dq|L@Uk9??!RS8 zQbAx&fmafZxr4aW^=AC;GS=v-oNZ$dsDQ_ zAAWH3aOuBlH%HFBuVojx8lD}yZ^zY^BVX!ep5FG((e|-*=dI1wzM9c(Q0cWv=1u>^U(_OXW&*yGIX zQA;P6(y6dJKrkTXDnSUx!B*oq8xJbqWzG@9tJj!Raaj5ZDjt*v5b&GWB5aeC&(Sl% z5(e>8Nivk$4M;W+N~T2x?tuUFZ$a<<^{W}rCgvX4-#7Ng`Suk@y1ltR`}GTVe}3pr zulyD#kIg@@G`()Yt?F6(pV>2c;l7|r)njiBxv#x)WbuUT4Wn0ezcnx;vTwIItboIL z15Z?`99Ddk;py$)Z2$Y+b33|kkkY@<0!t`LipsS|fMJQm3~-Bp)cLI{#|I#u@KaO( zLq?7jRFgdHP#JJz?p^*-jSGBO1{P0cClcXKF}ZPCl;h|?1AkY-nxs@-htlak_7`1q z7LbA*HY+{LTRc_r(p!U4dE$25o#Z~Y&sI^xXCey^#U#Gd}XAm z0K+16YPKC<$G|Po!G4IJ7yGc!Rz!AC=UlsvdF~D``^D5N}8*0pYI>=jmkx>{gD9$}i!P(|ibe zQS+I%Dtw2i#fAl#vc}|ES*9y@DRvCxl+4-^Jeo-%e%@*PQ;B(#8*ORKdJB1&xGPdGCaV7EReWZcka=Tf8!=yGuePmwJd zF|x<&oMD73{`EK&Aw|#-gID$UcmYX}%N+ zSPkN0y_FJj+w}-LAnL3ngw=m%!3>s0lt^!>aN_|;fT?Op5>*I;SPvy{Cta!$`j&z& zKp;h3(MI}+Wh@w?I}Of@bzQe>P84qLRXy?2_)YU4d*{}vLT$piYlWp}M}D$vgzVB4 znmf?`K$HUGh+t`pfDcHll9<^T?801dmR+n;MK@G99j0pQ7bJhVEz2VVG1<0_bqTKd z~D(lWS>|tp#-)DSBb9krdFO0u!td)gtVbW~XpRUzIAA zL3%Yt{-S8MNx2b6sc{(HZLanI{{#IdM||LDbf-hTUuN(X>$q4wZS1GR@vDtdy$X`7 z9CsMgY$C$MJ{%Y^M?f4inyIc0DM9J$+=N?313!3pTWPDhBL9UL*nwKusnAqVVSMwM z%5YDo@vd)%cYbw8%ilgc{AR$O+znrq@7+K9+4fI6-VmNxuZ$ls&I}O^A|&R>M>rIq zDh27AmrvNl3g^JO@9vZ*LECPqv=QjkeVje`-@g^qnzvnYd`KfabySiT|9V*7;sep$ z`=zyFyBfQlh@RJsDaULBO~R9hQE#=<8>*LJiHK9~xe#p;q8VKqAE1)ZWOh-II?{pw zFRc_iuoR6}b>G%Z4(nb)-l(6oMcvhL-kN6@&LC6zCr_?{f50nsF57m`e0$~fHL~nx z*VD&)-`7@U|EuA^t=7feUT+!t*+1X?*9TW8ym`0wow>F9g2oms`1!MKw~lxw%v`nQ zqXna{?QE0SL`r@}nv2pj=Ae6K3^c8{nqqu?(Qmyz?Dfejr_N6>id(=x2zYg`PJ}Ji zy};tDm0&`p8v%@+MXHvwUXCVLF-bPFLA-!OxtuuvB?O}}N$o0sgC6v%mNv*FiI5wk zj3xzt{^!LVSBf2}p1-W!{pY$X=N=jN@E~$-@BdL!|TSr}z zym&4M1zlJmIIZ;0t)d=EP}wU+W0d1Z8q#@4QlTOyKrXQl1Qj&Apz>&L8TBWD&v*e4b2X;$IfWE6=0x5GwSx1zF8e-tmNa_FbS2{YDGJ~tSXAfEQl)|2? zEH+&-mjL#e6kr#$NEx}mG4e@=kUBbY>XL-oA%KB`Oi7`YRBSK?rP@S-5pI>sW+mV- zVBYxMbL6|(>%^6De<~p1pbhe&@Bkv8jo%>h(zzWP1r7?ADJGFc`B1jnEe(+*i}V}t z@pQ`1-YW;>6lu_C)6hq~k>M!*^WTDupWAB|3x5=3p<)0>cQ4P~&?W4B5 z`lN}aPeoALsxEop5Tv32&y1r)EFHzH_grbVliItp+PAt&f+K0ZvFMWL<_#pMLl07u!@&tsGRS@;M(a?_q7>r2qLNZk+w^AZ*V2vsnHs2 zuaxzdP=L@3B_wtx3Z$+lA*Hx9G1uIRbYS#Y3(?0ia`eW0<|GXAi)v0w-LmML3Xc8A zZ=Ib(QZ$7V;2Z;dQg6&40g%V1G_zm4dV%^QMO)a>+-z06lO;gBRgyNCP6KI@51|$x zfhNKc!7ZBS&G%I&3184gp4LNP(ODo~XA9f(_nn5EZr?fB{EI6M!eOaGzTHKcaNW91 z-=iLC!^MIIV4?!H9E9Mrc|F{s0dL}+McZ-epq0kJRnlR3rHu3TB#lc04JWP7PB@k_ z`7OaOVNr?<)a&+~sY|5ex~+W?Md~-|fH7J$gJAkI36co_WB|$V^qFZB$KQ+ierJC% zb}^41PTQC~3Il%{YH3|LnE_DUlhOaKYG>7oR{<+QQlvPujvFv}WmYb0RFWar8sH6M z<29nWh74eKFxUjhR*XaE+1re5k)27%I>r;wnZlvbW(%f;D=llt4nm(ix#n_7X}u6A z_G6cFTey-sU-C0*aHmbU)|3DOQ}e<32L@^b7}@}Tue)WD8+L_0L14fuqZA@bo_q@r z|40~w9^&29;Db#lY2}{ffWSL~o%Gaoc=W5$0E6UY;rZnG5Sbe2EXVf9va z3Qv!gfNo=>sK^_M&+waRf8jvBna0T7sf6JI#)^0LH^-wDN`^6^EQS|nD;Jik_6_>n zYy$emNkgdF9*1*dVV$+*!QyG-p0RxLVTG1_R)t|I8&FLN1w1h#C@M~44mB9VFlQf9 zXr7~2WNBMb1CU27;1;f!_)l$&LuJy;Xo)C$bI)^M$r4q;m&n3J)T*2p%E3ve9zoB* z#-L*v+`H(PTB?ZU9utq@r)yDF9T!6-o#RrbJAz>nzZF-It6{E8F!NMc0*(;cO$u*6 z`q|FDF_&(g_~ll!9oNQ8yszawb^Y#N58PYq^gdbh;^FqAPLDr%uVg{5Efw#*)3R#e zZ}+v=uI(KD%)a<;pWTVw=`7TSxzeIqyJf0O(M9mEUhLZK_>S&79zVWg#NPy9eo!of zY9`8a4W&#dZn=h-n{$xZt}iy&X5}j$q8^6xZj$3Ih?Slto>#t-K#!YJ83R!mtv!&bi*r=6uEaje{-vv7;*ITtSFHMs@U4@n3$te1 zpRW0H_RKHxP4!>TtcA*-&=pHmwCsnX?`Az+(_;P1wXG}{piS%lSaRxflka{|we4VC za-Z_+rC>C{A4M2)TH7nd&6Jb18y~+cXXEs>2D?g2=izTi3K666}=SJdeRSc zs>xaJ-3HkK%VPO4)Z4aM7BBJVBXZY`t`$;>N-j&8U&vJGJqwk^6jA~TS%*413p|sy z_}KfjoPF5XFYD0198IDKbTEo+S}vT`o1>tuUjJyOtX;>;ps3&n_vXJ{pC_(Vno;6WzrKixbLQ)Y)tPs|Oz zBPRn>S?#=&DRGpMni6G@3{HBspNa)9MG`YbMc~w`{1H(hnY*DPqp@P+kD!dvy&SHJ zK#8=J%~$3cBd7%azII4vKPaRnQQeiWjcm`HT@|uAr+dDvz7|PTl>f*{6jpL7CAFy5 zzAj)?5m6`;wQZgNrIq#Kp5ZnHbeY7WCg3~bj*#oX5Q(_5l)J}K{=^@V$FK5jOo`YF zMZ0Bk1LMN%pc*Z<{4nd+)la=&TR-iU&udTJSo_)AYwep`-MnNCD37E^Lhd0N;Nv{e z5GCc3#m8wwZ>YA{Q>KBjQ}QGBZB9PoZCYom?)A*%xubPKR4$=G(mkmgUjQ|F3_9LQas|dCikemB|vW7sH?X1-hgncXhPu)>zoXQtC8DYjYX@niL*6 zuI8%?eXcD!zl6Q^J>MJu*Av4I%>g0$?0s#xrQ+e|TU~suYWt-B-1=d|eeDP1e@glc zyYTWmEvtw9_RH|Qe@a+*E&cq4Umm?}U6fXpHig7P;sJ_cVxhsn*j{YE@LF2?XNFyS z+Sa;dp%gRmu2=y)w5h>KTrHS-f0dWtuva-Kztt?ulS#A0|Ek4o02D?Y#-i3<7J)Sv zXW>>Q4_1u(orEGW5{y8jxB*=&p&*Qva{Hg6JV~-ZEWeDQi6hmer}1-$)URv;83GI( z7fD(qet^9<0!tz15`bxm*pvVBA@n)Q<`J9g2LB79b>#)+FZ7jxqvp6|j0YoA%m7=K ztwGhOP>>mLB*7|gP{uXVAaCzxu*vx5f(GN`di)!3FszGx$!?Yimv!8>j*gni&Uk#Q z5j(E0w+v}d}<){H1nfTDES9HPi$ljAXka;qJXU(+3U`eT!V)YuiUJl^<*$ z+9!!RT97N#EE$BG5EJYnn4s8!Fw~>RRG%X;Rh1M8Brpc#W3~=0ZOK@fJV7a-08OFL zf)~?)LjVy7IHHQRPD$aNB>)StgVgKW0xAk@Y6x?5+H=J-8*IA{efdz;jxIC7YRmR6 zbI-qZ&y!7D9rN9ROgOZ;YJbTG1X1N~h{sD|bB30(qFmc+vfJBPnk(^HQ6A#3_z~2pk!37|%@c!%+|_H(|Xwr{iQJBO$+Iwgj+t#|Qf;$V}yV z8epEXMH$BRaNfK22YSel&h0ap6`0ep7ya1U%YD|nVwY`V;_vKwg;OakkFcZ|&Yksw z;-xn4{+KonJfrct)ioAKlU1%>X%|%Qpv&^PX0WYphbD8iA&oP2v;s&j6*NFBu2>eM z>2A$o{DSxf^}*3(4mEACJV0g2n@b@?%pxCvYW0GhiZdVrV8A) zBO7LP-g<4+zSJHs*AJ`u*S+!?h0~nBTqZofIANco6A~Y75It(Fk2(Szm&UIeKbpY& zZ~cBQqy*GgGIO$OnQuxikop~mB+pV}YrZh&xPf8G>Ujz&cpiU2gkKV6MwZkMBp-J# zb5{{xnCvGifCt4?C+T%Du_6-PD}Smgw{k%$^!ESdya&?JC{FEHV{DVmAsiK+lUtJFCzu(F5@@-I1;T1F&TCVEu_q_CGG4gO(A1O4_f zp5TrguBjQUyb^ z{z6x5%VsRl7+mnvj9zQzYCQ)5T&tDh!5s^UT>g4t5Vtkk=6WgD+QQ;%L(-Ql%SY3) zlWQ}dTu`fJ2BktPw~mhgBc>{63VMTZTc$yvv#RDV!+-p-efvJibv})Kmu}7rvq8){ zS|w{@f~1YA$u=6Vu|N*}m7+%Wr)?fJNUzS6{wilL6V8Dq8J5<+iTL`aNa3T=ngT$^ z8?BbrShm?^0AT`4LjfC+a7!^#41-_Flubd}_^enXjFAuQF)rNhA(-MpE8SGJLw0#w z&-~p}=odyMzA7Lkct)$^1)U~{PEjJ4fEydlGwfEzMzQU zMdfcvG|Jy=xzA<(Q%=x33vb-2v~7K5fiw4X>Gjxl<1a4y!Lz#|wP5VU58B($-F@ag zcR~kQ`2O16Lw9>mnvm>?t&TnM=&cEVFY2EgQ7#W>BC@f!|l9^am*`#De@5~ih zWf8__&z8;%nfdU}voS&rLv1q5*t-`F24pbJO5O~P`@z8nWo+-X~GrJ-% zOWCg=BCS*#73?6()ForShk81u9^)8r=FJ6{Y|~?w?4fC_+YT8(Y7PK1T8N!i z-BcP(9aJk36=J=Z1cXphA^j))-6aV(QpbM%U1D+I6;`{$peMs16)L~<7tA8*vPMyplplXgkDouSLT!rruri6|o|+Tl;C}vZX-$4vPjyzRcmgxce?`-j98=Y% zL~Y^HnM@Qrsmgl%r>W9E(LwdGF6ZHcnV}aFB~+n3i%DmZzNIKhs!Vmf|*#{ z>aych;Iiwbk==8`MV^&D6^CR-S#qkDjP?Af`J29JZ4MR>Y53`!p(Lg2+Uy;Js%x?f z%EP-*4BS|pzCn%mACwF}a49h`NG|xj?5%I9MdV^N2)Xlf-;(V!t(p3q8}X*Hv_32( P)S`|O)y@pO|MUL?MGR(v literal 0 HcmV?d00001 From 5674d4059e180f939874b127eb9341e154d3f4e7 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 18 May 2026 01:52:48 +0000 Subject: [PATCH 28/39] feat: add serial output, graphics boot info, and TLS plaintext stripping to UEFI loader --- loongarch64-uefi-loader/src/abi.rs | 71 ++++++++++- loongarch64-uefi-loader/src/boot.rs | 165 ++++++++++++++++--------- loongarch64-uefi-loader/src/console.rs | 28 +++++ loongarch64-uefi-loader/src/flow.rs | 1 + loongarch64-uefi-loader/src/loader.rs | 2 +- loongarch64-uefi-loader/src/tcp4.rs | 131 ++++++++++++-------- 6 files changed, 287 insertions(+), 111 deletions(-) diff --git a/loongarch64-uefi-loader/src/abi.rs b/loongarch64-uefi-loader/src/abi.rs index 44fa8fa3..8dcd4f55 100644 --- a/loongarch64-uefi-loader/src/abi.rs +++ b/loongarch64-uefi-loader/src/abi.rs @@ -13,17 +13,29 @@ struct EfiStatus(u64); const EFI_SUCCESS: EfiStatus = EfiStatus(0); const EFI_ERROR_BIT: u64 = 1 << 63; +const EFI_INVALID_PARAMETER: EfiStatus = EfiStatus(EFI_ERROR_BIT | 2); const EFI_UNSUPPORTED: EfiStatus = EfiStatus(EFI_ERROR_BIT | 3); const EFI_BUFFER_TOO_SMALL: EfiStatus = EfiStatus(EFI_ERROR_BIT | 5); const EFI_NOT_READY: EfiStatus = EfiStatus(EFI_ERROR_BIT | 6); const EFI_DEVICE_ERROR: EfiStatus = EfiStatus(EFI_ERROR_BIT | 7); const EFI_NOT_FOUND: EfiStatus = EfiStatus(EFI_ERROR_BIT | 14); -const EFI_ALLOCATE_ANY_PAGES: EfiAllocateType = 0; const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 2; const EFI_LOADER_DATA: EfiMemoryType = 2; const EFI_CONVENTIONAL_MEMORY: EfiMemoryType = 7; const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; +const EFI_SERIAL_IO_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0xbb25cf6f, + data2: 0xf1d4, + data3: 0x11d2, + data4: [0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0xfd], +}; +const EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID: EfiGuid = EfiGuid { + data1: 0x9042a9de, + data2: 0x23dc, + data3: 0x4a38, + data4: [0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a], +}; const EVT_NOTIFY_SIGNAL: u32 = 0x0000_0200; const TPL_CALLBACK: EfiTpl = 8; const EFI_PAGE_SIZE: usize = 4096; @@ -79,6 +91,18 @@ struct EfiSimpleTextOutputProtocol { output_string: extern "C" fn(*mut EfiSimpleTextOutputProtocol, *const u16) -> EfiStatus, } +#[repr(C)] +struct EfiSerialIoProtocol { + revision: u32, + reset: usize, + set_attributes: usize, + set_control: usize, + get_control: usize, + write: extern "C" fn(*mut EfiSerialIoProtocol, *mut usize, *mut c_void) -> EfiStatus, + read: usize, + mode: *mut c_void, +} + #[repr(C)] struct EfiMemoryDescriptor { memory_type: u32, @@ -147,6 +171,9 @@ struct EfiBootServices { *mut usize, *mut *mut EfiHandle, ) -> EfiStatus, + locate_protocol: extern "C" fn(*const EfiGuid, *mut c_void, *mut *mut c_void) -> EfiStatus, + install_multiple_protocol_interfaces: usize, + uninstall_multiple_protocol_interfaces: usize, } #[repr(C)] @@ -170,6 +197,48 @@ struct EfiServiceBindingProtocol { destroy_child: extern "C" fn(*mut EfiServiceBindingProtocol, EfiHandle) -> EfiStatus, } +#[repr(C)] +struct EfiGraphicsOutputProtocol { + query_mode: usize, + set_mode: usize, + blt: usize, + mode: *mut EfiGraphicsOutputProtocolMode, +} + +#[repr(C)] +struct EfiGraphicsOutputProtocolMode { + max_mode: u32, + mode: u32, + info: *mut EfiGraphicsOutputModeInformation, + size_of_info: usize, + frame_buffer_base: u64, + frame_buffer_size: usize, +} + +#[repr(C)] +struct EfiGraphicsOutputModeInformation { + version: u32, + horizontal_resolution: u32, + vertical_resolution: u32, + pixel_format: u32, + pixel_information: [u32; 4], + pixels_per_scan_line: u32, +} + +#[repr(C)] +struct OstoolKernelBootInfo { + magic: u64, + version: u64, + framebuffer_base: u64, + framebuffer_size: u64, + horizontal_resolution: u32, + vertical_resolution: u32, + pixels_per_scan_line: u32, + pixel_format: u32, +} + +const OSTOOL_KERNEL_BOOT_INFO_MAGIC: u64 = 0x4f53_544f_4f4c_4249; + #[repr(C)] union EfiHttpConfigAccessPoint { ipv4_node: *mut EfiHttpv4AccessPoint, diff --git a/loongarch64-uefi-loader/src/boot.rs b/loongarch64-uefi-loader/src/boot.rs index 163087a3..f938bd5e 100644 --- a/loongarch64-uefi-loader/src/boot.rs +++ b/loongarch64-uefi-loader/src/boot.rs @@ -1,4 +1,14 @@ static mut MEMORY_MAP: [u8; MEMORY_MAP_MAX] = [0; MEMORY_MAP_MAX]; +static mut KERNEL_BOOT_INFO: OstoolKernelBootInfo = OstoolKernelBootInfo { + magic: OSTOOL_KERNEL_BOOT_INFO_MAGIC, + version: 1, + framebuffer_base: 0, + framebuffer_size: 0, + horizontal_resolution: 0, + vertical_resolution: 0, + pixels_per_scan_line: 0, + pixel_format: 0xffff_ffff, +}; fn page_count(size: u64) -> usize { ((size as usize) + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE @@ -117,6 +127,39 @@ fn print_memory_map(bs: *mut EfiBootServices, map_key_out: &mut usize) -> EfiSta status } +fn get_memory_map_key(bs: *mut EfiBootServices, map_key_out: &mut usize) -> EfiStatus { + let mut map_size = MEMORY_MAP_MAX; + let mut descriptor_size = 0usize; + let mut descriptor_version = 0u32; + let memory_map = core::ptr::addr_of_mut!(MEMORY_MAP) as *mut EfiMemoryDescriptor; + unsafe { + ((*bs).get_memory_map)( + &mut map_size, + memory_map, + map_key_out, + &mut descriptor_size, + &mut descriptor_version, + ) + } +} + +fn exit_boot_services_with_fresh_map(image: EfiHandle, bs: *mut EfiBootServices) -> EfiStatus { + let mut map_key = 0usize; + let mut status = get_memory_map_key(bs, &mut map_key); + if status.is_error() { + return status; + } + status = unsafe { ((*bs).exit_boot_services)(image, map_key) }; + if status == EFI_INVALID_PARAMETER { + status = get_memory_map_key(bs, &mut map_key); + if status.is_error() { + return status; + } + status = unsafe { ((*bs).exit_boot_services)(image, map_key) }; + } + status +} + fn print_memory_descriptor(label: &str, descriptor: *const EfiMemoryDescriptor) { if descriptor.is_null() { write_ascii(label); @@ -151,60 +194,7 @@ fn memory_descriptor_contains(desc: &EfiMemoryDescriptor, address: u64) -> bool start <= address && address < end } -fn memory_descriptor_contains_range(desc: &EfiMemoryDescriptor, target: u64, size: u64) -> bool { - if size == 0 { - return false; - } - let start = desc.physical_start; - let end = start + desc.number_of_pages * EFI_PAGE_SIZE as u64; - let target_end = target + size; - start <= target && target_end <= end -} - -fn target_range_has_memory_type( - bs: *mut EfiBootServices, - target: u64, - size: u64, - memory_type: EfiMemoryType, -) -> bool { - let mut map_size = MEMORY_MAP_MAX; - let mut map_key = 0usize; - let mut descriptor_size = 0usize; - let mut descriptor_version = 0u32; - let memory_map = core::ptr::addr_of_mut!(MEMORY_MAP) as *mut EfiMemoryDescriptor; - let status = unsafe { - ((*bs).get_memory_map)( - &mut map_size, - memory_map, - &mut map_key, - &mut descriptor_size, - &mut descriptor_version, - ) - }; - if status.is_error() || descriptor_size == 0 { - return false; - } - - let count = map_size / descriptor_size; - let mut i = 0usize; - while i < count { - let desc_ptr = unsafe { (memory_map as *const u8).add(i * descriptor_size) } - as *const EfiMemoryDescriptor; - let desc = unsafe { &*desc_ptr }; - if desc.memory_type == memory_type && memory_descriptor_contains_range(desc, target, size) - { - return true; - } - i += 1; - } - false -} - -fn print_target_memory_map_probe( - bs: *mut EfiBootServices, - target: u64, - size: u64, -) -> EfiStatus { +fn print_target_memory_map_probe(bs: *mut EfiBootServices, target: u64, size: u64) -> EfiStatus { let mut map_size = MEMORY_MAP_MAX; let mut map_key = 0usize; let mut descriptor_size = 0usize; @@ -270,9 +260,65 @@ fn print_target_memory_map_probe( status } -fn call_kernel(entry_point: u64) -> ! { - let entry: extern "C" fn() = unsafe { core::mem::transmute(entry_point as usize) }; - entry(); +fn prepare_kernel_boot_info(bs: *mut EfiBootServices) -> *const OstoolKernelBootInfo { + unsafe { + KERNEL_BOOT_INFO = OstoolKernelBootInfo { + magic: OSTOOL_KERNEL_BOOT_INFO_MAGIC, + version: 1, + framebuffer_base: 0, + framebuffer_size: 0, + horizontal_resolution: 0, + vertical_resolution: 0, + pixels_per_scan_line: 0, + pixel_format: 0xffff_ffff, + }; + } + + let mut gop_ptr: *mut c_void = null_mut(); + let status = unsafe { + ((*bs).locate_protocol)(&EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, null_mut(), &mut gop_ptr) + }; + write_status("kernel_boot_info_gop_status: ", status); + if !status.is_error() && !gop_ptr.is_null() { + let gop = gop_ptr as *mut EfiGraphicsOutputProtocol; + let mode = unsafe { (*gop).mode }; + if !mode.is_null() { + let info = unsafe { (*mode).info }; + unsafe { + KERNEL_BOOT_INFO.framebuffer_base = (*mode).frame_buffer_base; + KERNEL_BOOT_INFO.framebuffer_size = (*mode).frame_buffer_size as u64; + if !info.is_null() { + KERNEL_BOOT_INFO.horizontal_resolution = (*info).horizontal_resolution; + KERNEL_BOOT_INFO.vertical_resolution = (*info).vertical_resolution; + KERNEL_BOOT_INFO.pixels_per_scan_line = (*info).pixels_per_scan_line; + KERNEL_BOOT_INFO.pixel_format = (*info).pixel_format; + } + } + } + } + unsafe { + write_ascii("kernel_boot_info_ptr: 0x"); + write_hex64(core::ptr::addr_of!(KERNEL_BOOT_INFO) as u64); + write_ascii("\r\n"); + write_ascii("kernel_boot_info_fb_base: 0x"); + write_hex64(KERNEL_BOOT_INFO.framebuffer_base); + write_ascii("\r\n"); + write_ascii("kernel_boot_info_fb_size: "); + write_dec(KERNEL_BOOT_INFO.framebuffer_size); + write_ascii("\r\n"); + write_ascii("kernel_boot_info_resolution: "); + write_dec(KERNEL_BOOT_INFO.horizontal_resolution as u64); + write_ascii("x"); + write_dec(KERNEL_BOOT_INFO.vertical_resolution as u64); + write_ascii("\r\n"); + core::ptr::addr_of!(KERNEL_BOOT_INFO) + } +} + +fn call_kernel(entry_point: u64, boot_info: *const OstoolKernelBootInfo) -> ! { + let entry: extern "C" fn(*const OstoolKernelBootInfo) = + unsafe { core::mem::transmute(entry_point as usize) }; + entry(boot_info); loop { core::hint::spin_loop(); } @@ -440,9 +486,10 @@ fn try_manifest_with_fresh_http_child( return EFI_SUCCESS; } - let status = unsafe { ((*bs).exit_boot_services)(image, map_key) }; + let boot_info = prepare_kernel_boot_info(bs); + let status = exit_boot_services_with_fresh_map(image, bs); if !status.is_error() { - call_kernel(manifest.entry_point); + call_kernel(manifest.entry_point, boot_info); } write_status("exit_boot_services_status: ", status); write_ascii("jump_failed\r\n"); diff --git a/loongarch64-uefi-loader/src/console.rs b/loongarch64-uefi-loader/src/console.rs index 08cfd953..f345257a 100644 --- a/loongarch64-uefi-loader/src/console.rs +++ b/loongarch64-uefi-loader/src/console.rs @@ -1,4 +1,6 @@ static mut CONSOLE: *mut EfiSimpleTextOutputProtocol = null_mut(); +static mut SERIAL: *mut EfiSerialIoProtocol = null_mut(); + impl EfiStatus { fn is_error(self) -> bool { (self.0 & EFI_ERROR_BIT) != 0 @@ -9,6 +11,25 @@ fn console() -> *mut EfiSimpleTextOutputProtocol { unsafe { CONSOLE } } +fn configure_serial_output(bs: *mut EfiBootServices) { + let mut serial_ptr: *mut c_void = null_mut(); + let status = unsafe { + ((*bs).locate_protocol)(&EFI_SERIAL_IO_PROTOCOL_GUID, null_mut(), &mut serial_ptr) + }; + if !status.is_error() && !serial_ptr.is_null() { + unsafe { + SERIAL = serial_ptr as *mut EfiSerialIoProtocol; + } + } + write_status("serial_io_locate_status: ", status); + write_ascii("serial_io_enabled: "); + write_ascii(if unsafe { SERIAL }.is_null() { + "no\r\n" + } else { + "yes\r\n" + }); +} + fn write_ascii(s: &str) { write_bytes(s.as_bytes()); } @@ -32,6 +53,13 @@ fn write_bytes(s: &[u8]) { } pos += n; } + let serial = unsafe { SERIAL }; + if !serial.is_null() { + let mut written = s.len(); + unsafe { + ((*serial).write)(serial, &mut written, s.as_ptr() as *mut c_void); + } + } } fn write_hex64(value: u64) { diff --git a/loongarch64-uefi-loader/src/flow.rs b/loongarch64-uefi-loader/src/flow.rs index bd21a7d2..60fb79f1 100644 --- a/loongarch64-uefi-loader/src/flow.rs +++ b/loongarch64-uefi-loader/src/flow.rs @@ -102,6 +102,7 @@ extern "C" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTable) -> E if bs.is_null() { return EFI_SUCCESS; } + configure_serial_output(bs); print_protocol_handle_count( bs, diff --git a/loongarch64-uefi-loader/src/loader.rs b/loongarch64-uefi-loader/src/loader.rs index 874f7729..7a51f599 100644 --- a/loongarch64-uefi-loader/src/loader.rs +++ b/loongarch64-uefi-loader/src/loader.rs @@ -3,7 +3,7 @@ use core::ptr::{null_mut, read_volatile}; const OSTOOL_MANIFEST_URL: &str = env!("OSTOOL_MANIFEST_URL"); const OSTOOL_ENABLE_BOOT_JUMP: bool = cfg!(ostool_enable_boot_jump); -const OSTOOL_LOONGARCH64_LOADER_BUILD_ID: &str = "start43-real-boot-jump"; +const OSTOOL_LOONGARCH64_LOADER_BUILD_ID: &str = "start46-strip-tls-plaintext-header"; include!("abi.rs"); include!("console.rs"); diff --git a/loongarch64-uefi-loader/src/tcp4.rs b/loongarch64-uefi-loader/src/tcp4.rs index 452d71ab..9a854bfe 100644 --- a/loongarch64-uefi-loader/src/tcp4.rs +++ b/loongarch64-uefi-loader/src/tcp4.rs @@ -445,7 +445,11 @@ fn https_path_from_url<'a>(url: &'a [u8]) -> Result<&'a [u8], EfiStatus> { Err(EFI_UNSUPPORTED) } -fn build_http_get_request(path: &[u8], connection: &[u8], out: &mut [u8]) -> Result { +fn build_http_get_request( + path: &[u8], + connection: &[u8], + out: &mut [u8], +) -> Result { const PREFIX: &[u8] = b"GET "; const VERSION_HOST: &[u8] = b" HTTP/1.1\r\nHost: 10.3.10.229\r\nConnection: "; const SUFFIX: &[u8] = b"\r\n\r\n"; @@ -540,6 +544,36 @@ fn find_tls_app_record_start(bytes: &[u8], len: usize) -> Option { None } +fn tls_plaintext_payload_offset(bytes: *const u8, len: usize) -> usize { + if len < 5 || bytes.is_null() { + return 0; + } + let content_type = unsafe { read_volatile(bytes) }; + let version_major = unsafe { read_volatile(bytes.add(1)) }; + let version_minor = unsafe { read_volatile(bytes.add(2)) }; + if content_type == 23 && version_major == 3 && version_minor == 3 { + 5 + } else { + 0 + } +} + +fn print_kernel_entry_first16(entry: u64) { + write_ascii("tcp4_tls_probe_kernel_entry_first16: "); + let ptr = entry as *const u8; + let mut i = 0usize; + while i < 16 { + if i > 0 { + write_ascii(","); + } + write_ascii("0x"); + let b = unsafe { read_volatile(ptr.add(i)) }; + write_hex64(b as u64); + i += 1; + } + write_ascii("\r\n"); +} + fn tcp4_receive_kernel_once( bs: *mut EfiBootServices, tcp4: *mut EfiTcp4Protocol, @@ -624,12 +658,7 @@ fn tcp4_receive_kernel_once( write_ascii("tcp4_tls_probe_kernel_rx_len: "); write_dec(*received_len as u64); write_ascii("\r\n"); - print_tcp4_first5( - "tcp4_tls_probe_kernel_rx", - "_first5: ", - out, - *received_len, - ); + print_tcp4_first5("tcp4_tls_probe_kernel_rx", "_first5: ", out, *received_len); } unsafe { ((*bs).close_event)(event); @@ -669,8 +698,13 @@ fn https_send_get_with_pre_receive( return EFI_BUFFER_TOO_SMALL; } - let (encrypt_status, encrypted_len, encrypted_ptr) = - tls_process_single_fragment(tls, &mut plain_record, plain_record_len, EFI_TLS_ENCRYPT, label); + let (encrypt_status, encrypted_len, encrypted_ptr) = tls_process_single_fragment( + tls, + &mut plain_record, + plain_record_len, + EFI_TLS_ENCRYPT, + label, + ); if encrypt_status.is_error() || encrypted_len == 0 { return encrypt_status; } @@ -752,8 +786,13 @@ fn https_get_manifest_probe( return None; } if decrypted_len > 0 { + let payload_offset = + tls_plaintext_payload_offset(decrypted_ptr as *const u8, decrypted_len); + let decrypted_ptr = unsafe { (decrypted_ptr as *mut u8).add(payload_offset) }; + let decrypted_len = decrypted_len - payload_offset; let mut decrypted = [0u8; 1024]; - let decrypted_len = copy_from_ptr(&mut decrypted, decrypted_ptr, decrypted_len); + let decrypted_len = + copy_from_ptr(&mut decrypted, decrypted_ptr as *mut c_void, decrypted_len); if loop_count == 0 { print_ascii_prefix("tcp4_tls_probe_app_decrypt", &decrypted, decrypted_len); } @@ -848,48 +887,25 @@ fn https_download_kernel_probe( let pages = page_count(manifest.kernel_size); let mut target = manifest.kernel_load_addr; - let mut allocate_status = unsafe { + let allocate_status = unsafe { ((*bs).allocate_pages)(EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, pages, &mut target) }; - write_status("tcp4_tls_probe_kernel_allocate_pages_status: ", allocate_status); + write_status( + "tcp4_tls_probe_kernel_allocate_pages_status: ", + allocate_status, + ); write_ascii("tcp4_tls_probe_kernel_target_addr: 0x"); write_hex64(target); write_ascii("\r\n"); if allocate_status.is_error() || target != manifest.kernel_load_addr { - let target_is_loader_data = target_range_has_memory_type( - bs, - manifest.kernel_load_addr, - manifest.kernel_size, - EFI_LOADER_DATA, - ); - write_ascii("tcp4_tls_probe_kernel_target_loader_data_after_allocate: "); - write_ascii(if target_is_loader_data { - "yes\r\n" + *loaded_at_manifest_addr = false; + write_ascii("tcp4_tls_probe_kernel_fixed_address_required\r\n"); + print_target_memory_map_probe(bs, manifest.kernel_load_addr, manifest.kernel_size); + return if allocate_status.is_error() { + allocate_status } else { - "no\r\n" - }); - if target == manifest.kernel_load_addr && target_is_loader_data { - write_ascii("tcp4_tls_probe_kernel_allocate_error_accepted: yes\r\n"); - *loaded_at_manifest_addr = true; - } else { - *loaded_at_manifest_addr = false; - write_ascii("tcp4_tls_probe_kernel_staging_fallback: yes\r\n"); - target = 0; - allocate_status = unsafe { - ((*bs).allocate_pages)(EFI_ALLOCATE_ANY_PAGES, EFI_LOADER_DATA, pages, &mut target) - }; - write_status( - "tcp4_tls_probe_kernel_staging_allocate_pages_status: ", - allocate_status, - ); - write_ascii("tcp4_tls_probe_kernel_staging_addr: 0x"); - write_hex64(target); - write_ascii("\r\n"); - if allocate_status.is_error() { - return allocate_status; - } - *loaded_at_manifest_addr = target == manifest.kernel_load_addr; - } + EFI_DEVICE_ERROR + }; } else { *loaded_at_manifest_addr = true; } @@ -1096,6 +1112,10 @@ fn https_download_kernel_probe( write_ascii("\r\n"); break; } + let payload_offset = + tls_plaintext_payload_offset(decrypted_ptr as *const u8, decrypted_len); + let decrypted_ptr = unsafe { (decrypted_ptr as *mut u8).add(payload_offset) }; + let decrypted_len = decrypted_len - payload_offset; let mut offset = 0usize; let mut data_len = decrypted_len; @@ -1133,7 +1153,11 @@ fn https_download_kernel_probe( if saw_header && data_len > 0 { let remaining = (manifest.kernel_size - downloaded) as usize; - let copy_len = if data_len > remaining { remaining } else { data_len }; + let copy_len = if data_len > remaining { + remaining + } else { + data_len + }; let src = unsafe { (decrypted_ptr as *const u8).add(offset) }; let dst = (target + downloaded) as *mut u8; let mut i = 0usize; @@ -1334,7 +1358,11 @@ fn tcp4_transmit_with_pre_receive( } else if !pre_rx_submit_status.is_error() { let completion = poll_tcp4(tcp4, &rx_token.completion_token); write_prefixed_status(label, "_pre_rx_completion", completion); - write_prefixed_status(label, "_pre_rx_token_status", rx_token.completion_token.status); + write_prefixed_status( + label, + "_pre_rx_token_status", + rx_token.completion_token.status, + ); if completion.is_error() { *received_len = 0; } else { @@ -1677,7 +1705,8 @@ fn tcp4_tls_clienthello_probe(image: EfiHandle, bs: *mut EfiBootServices) -> Efi write_dec(manifest.kernel_size); write_ascii("\r\n"); let mut loaded_at_manifest_addr = false; - rx_status = https_download_kernel_probe(bs, tcp4, tls, &manifest, &mut loaded_at_manifest_addr); + rx_status = + https_download_kernel_probe(bs, tcp4, tls, &manifest, &mut loaded_at_manifest_addr); write_status("tcp4_tls_probe_kernel_download_status: ", rx_status); if !rx_status.is_error() { let mut map_key = 0usize; @@ -1700,9 +1729,11 @@ fn tcp4_tls_clienthello_probe(image: EfiHandle, bs: *mut EfiBootServices) -> Efi } else if !OSTOOL_ENABLE_BOOT_JUMP || status.is_error() { write_ascii("jump_skipped: boot jump disabled\r\n"); } else { - let exit_status = unsafe { ((*bs).exit_boot_services)(image, map_key) }; + print_kernel_entry_first16(manifest.entry_point); + let boot_info = prepare_kernel_boot_info(bs); + let exit_status = exit_boot_services_with_fresh_map(image, bs); if !exit_status.is_error() { - call_kernel(manifest.entry_point); + call_kernel(manifest.entry_point, boot_info); } write_status("exit_boot_services_status: ", exit_status); write_ascii("jump_failed\r\n"); From f5e9fd2aa1ec42190da6e897319cae045f1a287d Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 18 May 2026 05:56:53 +0000 Subject: [PATCH 29/39] feat: add HTTPS static server for HTTP Boot and fresh TLS connection in UEFI loader --- Cargo.lock | 1 + loongarch64-uefi-loader/Makefile | 2 +- loongarch64-uefi-loader/README.md | 2 +- loongarch64-uefi-loader/src/tcp4.rs | 360 +++++++++++++++++++- ostool-server/Cargo.toml | 1 + ostool-server/src/api/router.rs | 13 +- ostool-server/src/config.rs | 32 ++ ostool-server/src/http_boot.rs | 1 + ostool-server/src/http_boot/https.rs | 251 ++++++++++++++ ostool-server/src/lib.rs | 10 +- ostool-server/src/main.rs | 6 +- ostool-server/src/proxy_dhcp.rs | 4 +- ostool-server/tests/session_ws_lifecycle.rs | 1 + scripts/https_static_server.py | 6 +- 14 files changed, 668 insertions(+), 22 deletions(-) create mode 100644 ostool-server/src/http_boot/https.rs diff --git a/Cargo.lock b/Cargo.lock index 5f04c330..8c190fa4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2237,6 +2237,7 @@ dependencies = [ "thiserror 2.0.18", "tokio", "tokio-modbus", + "tokio-rustls", "tokio-serial", "tokio-tungstenite", "toml", diff --git a/loongarch64-uefi-loader/Makefile b/loongarch64-uefi-loader/Makefile index 36aef23f..65c5c2cd 100644 --- a/loongarch64-uefi-loader/Makefile +++ b/loongarch64-uefi-loader/Makefile @@ -11,7 +11,7 @@ OUT_DIR ?= ../target/loongarch64-uefi-loader TARGET := $(OUT_DIR)/BOOTLOONGARCH64.EFI ELF := $(OUT_DIR)/ostool-loongarch64-loader.elf -MANIFEST_URL ?= http://10.3.10.229:2999/boot/boards/loongchip-httpboot-smoke/current/manifest.json +MANIFEST_URL ?= https://10.3.10.229:3443/boot/boards/loongchip-httpboot-smoke/current/manifest.json ENABLE_BOOT_JUMP ?= 0 LDFLAGS := -nostdlib -znocombreloc -T loader.lds diff --git a/loongarch64-uefi-loader/README.md b/loongarch64-uefi-loader/README.md index e3e796e3..33332da9 100644 --- a/loongarch64-uefi-loader/README.md +++ b/loongarch64-uefi-loader/README.md @@ -33,7 +33,7 @@ Override the manifest URL: ```bash make -C loongarch64-uefi-loader \ - MANIFEST_URL=http://10.3.10.229:2999/boot/boards/loongchip-httpboot-smoke/current/manifest.json + MANIFEST_URL=https://10.3.10.229:3443/boot/boards/loongchip-httpboot-smoke/current/manifest.json ``` Enable the final jump only after download and memory-map observations are stable: diff --git a/loongarch64-uefi-loader/src/tcp4.rs b/loongarch64-uefi-loader/src/tcp4.rs index 9a854bfe..12224690 100644 --- a/loongarch64-uefi-loader/src/tcp4.rs +++ b/loongarch64-uefi-loader/src/tcp4.rs @@ -742,12 +742,15 @@ fn https_get_manifest_probe( return None; } + let manifest_path = match https_path_from_url(OSTOOL_MANIFEST_URL.as_bytes()) { + Ok(path) => path, + Err(status) => { + *rx_status = status; + return None; + } + }; let mut http_get = [0u8; 512]; - let http_get_len = match build_http_get_request( - b"/boot/boards/loongchip-httpboot-smoke/current/manifest.json", - b"keep-alive", - &mut http_get, - ) { + let http_get_len = match build_http_get_request(manifest_path, b"keep-alive", &mut http_get) { Ok(len) => len, Err(status) => { *rx_status = status; @@ -1207,6 +1210,344 @@ fn https_download_kernel_probe( EFI_SUCCESS } +fn close_tcp4_child( + bs: *mut EfiBootServices, + tcp4: *mut EfiTcp4Protocol, + label: &str, +) { + let mut close_event = null_mut(); + let close_event_status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut close_event, + ) + }; + write_prefixed_status(label, "_close_event_status", close_event_status); + if !close_event_status.is_error() { + let mut close_token = EfiTcp4CloseToken { + completion_token: EfiTcp4CompletionToken { + event: close_event, + status: EFI_NOT_READY, + }, + abort_on_close: 1, + }; + let close_submit_status = unsafe { ((*tcp4).close)(tcp4, &mut close_token) }; + write_prefixed_status(label, "_close_submit_status", close_submit_status); + if !close_submit_status.is_error() { + let close_completion = poll_tcp4(tcp4, &close_token.completion_token); + write_prefixed_status(label, "_close_completion", close_completion); + } + unsafe { + ((*bs).close_event)(close_event); + } + } +} + +fn connect_tcp4_child( + bs: *mut EfiBootServices, + tcp_binding: *mut EfiServiceBindingProtocol, + out_child: &mut EfiHandle, + label: &str, +) -> Result<*mut EfiTcp4Protocol, EfiStatus> { + *out_child = null_mut(); + let status = unsafe { ((*tcp_binding).create_child)(tcp_binding, out_child) }; + write_prefixed_status(label, "_tcp_create_child_status", status); + if status.is_error() || (*out_child).is_null() { + return Err(if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }); + } + + let tcp4 = match open_protocol::(bs, *out_child, &EFI_TCP4_PROTOCOL_GUID) { + Ok(tcp4) => { + write_prefixed_status(label, "_tcp_protocol_status", EFI_SUCCESS); + tcp4 + } + Err(status) => { + write_prefixed_status(label, "_tcp_protocol_status", status); + unsafe { + ((*tcp_binding).destroy_child)(tcp_binding, *out_child); + } + *out_child = null_mut(); + return Err(status); + } + }; + + let mut config = EfiTcp4ConfigData { + type_of_service: 0, + time_to_live: 64, + access_point: EfiTcp4AccessPoint { + use_default_address: 1, + station_address: [0; 4], + subnet_mask: [0; 4], + station_port: 0, + remote_address: [10, 3, 10, 229], + remote_port: 3443, + active_flag: 1, + }, + control_option: EfiTcp4Option { + receive_buffer_size: 0, + send_buffer_size: 0, + max_syn_back_log: 0, + connection_timeout: 0, + data_retries: 0, + fin_timeout: 0, + time_wait_timeout: 0, + keep_alive_probes: 0, + keep_alive_time: 0, + keep_alive_interval: 0, + enable_nagle: 0, + enable_time_stamp: 0, + enable_window_scaling: 0, + enable_selective_ack: 0, + enable_path_mtu_discovery: 0, + }, + }; + let status = unsafe { ((*tcp4).configure)(tcp4, &mut config) }; + write_prefixed_status(label, "_tcp_configure_status", status); + if status.is_error() { + unsafe { + ((*tcp_binding).destroy_child)(tcp_binding, *out_child); + } + *out_child = null_mut(); + return Err(status); + } + + let mut connect_event = null_mut(); + let status = unsafe { + ((*bs).create_event)( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + Some(noop_event), + null_mut(), + &mut connect_event, + ) + }; + write_prefixed_status(label, "_connect_event_status", status); + if status.is_error() { + unsafe { + ((*tcp4).configure)(tcp4, null_mut()); + ((*tcp_binding).destroy_child)(tcp_binding, *out_child); + } + *out_child = null_mut(); + return Err(status); + } + + let mut connect_token = EfiTcp4ConnectionToken { + completion_token: EfiTcp4CompletionToken { + event: connect_event, + status: EFI_NOT_READY, + }, + }; + let submit_status = unsafe { ((*tcp4).connect)(tcp4, &mut connect_token) }; + write_prefixed_status(label, "_connect_submit_status", submit_status); + let connect_status = if submit_status.is_error() { + submit_status + } else { + poll_tcp4(tcp4, &connect_token.completion_token) + }; + write_prefixed_status(label, "_connect_completion", connect_status); + unsafe { + ((*bs).close_event)(connect_event); + } + if connect_status.is_error() { + unsafe { + ((*tcp4).configure)(tcp4, null_mut()); + ((*tcp_binding).destroy_child)(tcp_binding, *out_child); + } + *out_child = null_mut(); + return Err(connect_status); + } + + Ok(tcp4) +} + +fn complete_tls_handshake_on_fresh_connection( + bs: *mut EfiBootServices, + tcp4: *mut EfiTcp4Protocol, + tls: *mut EfiTlsProtocol, + clienthello: &mut [u8], + clienthello_len: usize, +) -> EfiStatus { + tls_session_state(tls, "tcp4_tls_kernel_fresh_initial"); + + let mut rx = [0u8; 8192]; + let mut rx_len = 0usize; + let mut rx_status = tcp4_transmit_with_pre_receive( + bs, + tcp4, + &mut clienthello[..clienthello_len], + &mut rx, + &mut rx_len, + "tcp4_tls_kernel_fresh", + ); + + let mut tls_out = [0u8; 8192]; + let mut round = 0usize; + while !rx_status.is_error() && round < 4 { + let label = match round { + 0 => "tcp4_tls_kernel_fresh_hs0", + 1 => "tcp4_tls_kernel_fresh_hs1", + 2 => "tcp4_tls_kernel_fresh_hs2", + _ => "tcp4_tls_kernel_fresh_hs3", + }; + + tls_session_state(tls, label); + let mut tls_out_len = tls_out.len(); + let build_status = unsafe { + ((*tls).build_response_packet)( + tls, + rx.as_mut_ptr(), + rx_len, + tls_out.as_mut_ptr(), + &mut tls_out_len, + ) + }; + write_prefixed_status(label, "_build_response_status", build_status); + write_ascii(label); + write_ascii("_build_response_len: "); + write_dec(tls_out_len as u64); + write_ascii("\r\n"); + print_tcp4_first5(label, "_build_response_first5: ", &tls_out, tls_out_len); + let state = tls_session_state(tls, label); + if build_status.is_error() { + return build_status; + } + if state == EFI_TLS_SESSION_DATA_TRANSFERRING { + return EFI_SUCCESS; + } + if tls_out_len == 0 || tls_out_len > tls_out.len() { + return EFI_NOT_READY; + } + rx_status = tcp4_transmit_with_pre_receive( + bs, + tcp4, + &mut tls_out[..tls_out_len], + &mut rx, + &mut rx_len, + label, + ); + round += 1; + } + + if rx_status.is_error() { + rx_status + } else { + EFI_NOT_READY + } +} + +fn https_download_kernel_fresh_probe( + bs: *mut EfiBootServices, + tcp_binding: *mut EfiServiceBindingProtocol, + tls_binding: *mut EfiServiceBindingProtocol, + manifest: &Manifest, + loaded_at_manifest_addr: &mut bool, +) -> EfiStatus { + write_ascii("tcp4_tls_probe_kernel_fresh_start\r\n"); + + let mut tls_child = null_mut(); + let status = unsafe { ((*tls_binding).create_child)(tls_binding, &mut tls_child) }; + write_status("tcp4_tls_probe_kernel_fresh_tls_create_child_status: ", status); + if status.is_error() || tls_child.is_null() { + return if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }; + } + + let mut clienthello = [0u8; 2048]; + let mut clienthello_len = 0usize; + let mut status = build_tls_clienthello_on_child( + bs, + tls_child, + &mut clienthello, + &mut clienthello_len, + "tcp4_tls_probe_kernel_fresh_tls_config", + ); + write_status( + "tcp4_tls_probe_kernel_fresh_build_clienthello_status: ", + status, + ); + write_ascii("tcp4_tls_probe_kernel_fresh_clienthello_len: "); + write_dec(clienthello_len as u64); + write_ascii("\r\n"); + if status.is_error() || clienthello_len == 0 || clienthello_len > clienthello.len() { + unsafe { + ((*tls_binding).destroy_child)(tls_binding, tls_child); + } + return status; + } + + let mut tcp_child = null_mut(); + let tcp4 = match connect_tcp4_child( + bs, + tcp_binding, + &mut tcp_child, + "tcp4_tls_probe_kernel_fresh", + ) { + Ok(tcp4) => tcp4, + Err(status) => { + unsafe { + ((*tls_binding).destroy_child)(tls_binding, tls_child); + } + return status; + } + }; + + let tls = match open_protocol::(bs, tls_child, &EFI_TLS_PROTOCOL_GUID) { + Ok(tls) => { + write_status( + "tcp4_tls_probe_kernel_fresh_tls_protocol_reopen_status: ", + EFI_SUCCESS, + ); + tls + } + Err(status) => { + write_status( + "tcp4_tls_probe_kernel_fresh_tls_protocol_reopen_status: ", + status, + ); + close_tcp4_child(bs, tcp4, "tcp4_tls_probe_kernel_fresh"); + unsafe { + ((*tcp4).configure)(tcp4, null_mut()); + ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); + ((*tls_binding).destroy_child)(tls_binding, tls_child); + } + return status; + } + }; + + status = complete_tls_handshake_on_fresh_connection( + bs, + tcp4, + tls, + &mut clienthello, + clienthello_len, + ); + write_status( + "tcp4_tls_probe_kernel_fresh_handshake_status: ", + status, + ); + if !status.is_error() { + status = https_download_kernel_probe(bs, tcp4, tls, manifest, loaded_at_manifest_addr); + } + + close_tcp4_child(bs, tcp4, "tcp4_tls_probe_kernel_fresh"); + unsafe { + ((*tcp4).configure)(tcp4, null_mut()); + ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); + ((*tls_binding).destroy_child)(tls_binding, tls_child); + } + status +} + fn tls_process_single_fragment( tls: *mut EfiTlsProtocol, bytes: &mut [u8], @@ -1705,8 +2046,13 @@ fn tcp4_tls_clienthello_probe(image: EfiHandle, bs: *mut EfiBootServices) -> Efi write_dec(manifest.kernel_size); write_ascii("\r\n"); let mut loaded_at_manifest_addr = false; - rx_status = - https_download_kernel_probe(bs, tcp4, tls, &manifest, &mut loaded_at_manifest_addr); + rx_status = https_download_kernel_fresh_probe( + bs, + tcp_binding, + tls_binding, + &manifest, + &mut loaded_at_manifest_addr, + ); write_status("tcp4_tls_probe_kernel_download_status: ", rx_status); if !rx_status.is_error() { let mut map_key = 0usize; diff --git a/ostool-server/Cargo.toml b/ostool-server/Cargo.toml index 0bc86071..35f073aa 100644 --- a/ostool-server/Cargo.toml +++ b/ostool-server/Cargo.toml @@ -43,6 +43,7 @@ serialport = "4.6" tftpd = "0.5" thiserror = {workspace = true} tokio = {workspace = true, features = ["full"]} +tokio-rustls = "0.26" tokio-modbus = {version = "0.17.0", default-features = false, features = ["rtu"]} tokio-serial = "5.4" toml = {workspace = true} diff --git a/ostool-server/src/api/router.rs b/ostool-server/src/api/router.rs index 54be0975..06bd4f16 100644 --- a/ostool-server/src/api/router.rs +++ b/ostool-server/src/api/router.rs @@ -1485,11 +1485,13 @@ fn http_boot_url( ) -> Result { let relative_path = normalize_relative_path(relative_path) .map_err(|err| ApiError::bad_request(err.to_string()))?; - let base_url = config - .http_boot - .public_base_url - .clone() - .unwrap_or_else(|| format!("http://{}", config.listen_addr)); + let base_url = config.http_boot.public_base_url.clone().unwrap_or_else(|| { + if config.http_boot.https.enabled { + format!("https://{}", config.http_boot.https.listen_addr) + } else { + format!("http://{}", config.listen_addr) + } + }); let base_url = base_url.trim_end_matches('/'); Ok(format!( "{base_url}/boot/boards/{board_id}/current/{relative_path}" @@ -1813,6 +1815,7 @@ mod tests { dtb_dir: root.join("dtbs"), tftp: TftpConfig::Builtin(BuiltinTftpConfig::default_with_root(root.join("tftp"))), http_boot: crate::config::HttpBootConfig::default_with_root(root.join("http-boot")), + proxy_dhcp: crate::config::ProxyDhcpConfig::default(), network: crate::TftpNetworkConfig { interface: "lo".into(), }, diff --git a/ostool-server/src/config.rs b/ostool-server/src/config.rs index 2361fcc9..1595523d 100644 --- a/ostool-server/src/config.rs +++ b/ostool-server/src/config.rs @@ -156,6 +156,10 @@ impl ServerConfig { self.board_dir = absolutize_path(&config_dir, &self.board_dir); self.dtb_dir = absolutize_path(&config_dir, &self.dtb_dir); self.http_boot.root_dir = absolutize_path(&config_dir, &self.http_boot.root_dir); + self.http_boot.https.cert_path = + absolutize_path(&config_dir, &self.http_boot.https.cert_path); + self.http_boot.https.key_path = + absolutize_path(&config_dir, &self.http_boot.https.key_path); match &mut self.tftp { TftpConfig::Builtin(cfg) => { @@ -188,12 +192,15 @@ pub struct HttpBootConfig { pub enabled: bool, pub root_dir: PathBuf, pub public_base_url: Option, + #[serde(default)] + pub https: HttpBootHttpsConfig, } impl HttpBootConfig { pub fn default_with_root(root_dir: PathBuf) -> Self { Self { enabled: true, + https: HttpBootHttpsConfig::default_with_root(&root_dir), root_dir, public_base_url: None, } @@ -206,6 +213,31 @@ impl Default for HttpBootConfig { } } +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +pub struct HttpBootHttpsConfig { + pub enabled: bool, + pub listen_addr: SocketAddr, + pub cert_path: PathBuf, + pub key_path: PathBuf, +} + +impl HttpBootHttpsConfig { + pub fn default_with_root(root_dir: &Path) -> Self { + Self { + enabled: false, + listen_addr: SocketAddr::from(([0, 0, 0, 0], 3443)), + cert_path: root_dir.join("certs/httpboot.crt"), + key_path: root_dir.join("certs/httpboot.key"), + } + } +} + +impl Default for HttpBootHttpsConfig { + fn default() -> Self { + Self::default_with_root(Path::new(".ostool-server/http-boot")) + } +} + #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] pub struct ProxyDhcpConfig { pub enabled: bool, diff --git a/ostool-server/src/http_boot.rs b/ostool-server/src/http_boot.rs index d3ab9696..8dc13a9c 100644 --- a/ostool-server/src/http_boot.rs +++ b/ostool-server/src/http_boot.rs @@ -1 +1,2 @@ pub mod files; +pub mod https; diff --git a/ostool-server/src/http_boot/https.rs b/ostool-server/src/http_boot/https.rs new file mode 100644 index 00000000..37c49a99 --- /dev/null +++ b/ostool-server/src/http_boot/https.rs @@ -0,0 +1,251 @@ +use std::{ + path::{Path, PathBuf}, + sync::Arc, +}; + +use anyhow::{Context, bail}; +use log::info; +use tokio::{ + fs, + io::{AsyncBufReadExt, AsyncWriteExt, BufReader}, + net::{TcpListener, TcpStream}, +}; +use tokio_rustls::{ + TlsAcceptor, + rustls::{ + ServerConfig as TlsServerConfig, + pki_types::{CertificateDer, pem::PemObject}, + }, +}; + +use crate::{config::HttpBootConfig, tftp::files::normalize_relative_path}; + +const MAX_REQUEST_LINE: usize = 8192; +const MAX_HEADER_LINE: usize = 8192; + +pub async fn spawn_https_static_server( + config: &HttpBootConfig, +) -> anyhow::Result>> { + if !config.enabled || !config.https.enabled { + return Ok(None); + } + + let tls_config = Arc::new(load_tls_config(config).await?); + let root_dir = Arc::new(config.root_dir.clone()); + let listener = TcpListener::bind(config.https.listen_addr) + .await + .with_context(|| { + format!( + "failed to bind HTTP Boot HTTPS listener {}", + config.https.listen_addr + ) + })?; + let local_addr = listener.local_addr()?; + info!( + "HTTP Boot HTTPS static server listening on https://{} root={}", + local_addr, + root_dir.display() + ); + + let acceptor = TlsAcceptor::from(tls_config); + Ok(Some(tokio::spawn(async move { + loop { + let (stream, peer) = match listener.accept().await { + Ok(value) => value, + Err(err) => { + log::warn!("failed to accept HTTP Boot HTTPS connection: {err:#}"); + continue; + } + }; + let acceptor = acceptor.clone(); + let root_dir = root_dir.clone(); + tokio::spawn(async move { + if let Err(err) = serve_tls_connection(acceptor, stream, root_dir).await { + log::debug!("HTTP Boot HTTPS connection from {peer} failed: {err:#}"); + } + }); + } + }))) +} + +async fn load_tls_config(config: &HttpBootConfig) -> anyhow::Result { + let cert_bytes = fs::read(&config.https.cert_path).await.with_context(|| { + format!( + "failed to read HTTP Boot HTTPS certificate {}", + config.https.cert_path.display() + ) + })?; + let key_bytes = fs::read(&config.https.key_path).await.with_context(|| { + format!( + "failed to read HTTP Boot HTTPS private key {}", + config.https.key_path.display() + ) + })?; + let certs = CertificateDer::pem_slice_iter(&cert_bytes) + .collect::, _>>() + .context("failed to parse HTTP Boot HTTPS certificate PEM")?; + if certs.is_empty() { + bail!( + "HTTP Boot HTTPS certificate {} contains no certificates", + config.https.cert_path.display() + ); + } + let key = tokio_rustls::rustls::pki_types::PrivateKeyDer::from_pem_slice(&key_bytes) + .context("failed to parse HTTP Boot HTTPS private key PEM")?; + + TlsServerConfig::builder() + .with_no_client_auth() + .with_single_cert(certs, key) + .context("failed to build HTTP Boot HTTPS TLS config") +} + +async fn serve_tls_connection( + acceptor: TlsAcceptor, + stream: TcpStream, + root_dir: Arc, +) -> anyhow::Result<()> { + let stream = acceptor.accept(stream).await?; + let mut reader = BufReader::new(stream); + let mut request_line = String::new(); + read_limited_line(&mut reader, &mut request_line, MAX_REQUEST_LINE).await?; + let request = parse_request_line(&request_line)?; + + loop { + let mut header = String::new(); + read_limited_line(&mut reader, &mut header, MAX_HEADER_LINE).await?; + if header == "\r\n" || header == "\n" || header.is_empty() { + break; + } + } + + let response = match request { + HttpBootRequest::Get(path) => file_response(&root_dir, path, true).await, + HttpBootRequest::Head(path) => file_response(&root_dir, path, false).await, + HttpBootRequest::MethodNotAllowed => http_response( + "405 Method Not Allowed", + "text/plain", + b"method not allowed".to_vec(), + true, + ), + HttpBootRequest::BadRequest => http_response( + "400 Bad Request", + "text/plain", + b"bad request".to_vec(), + true, + ), + }; + + let stream = reader.get_mut(); + stream.write_all(&response).await?; + stream.flush().await?; + Ok(()) +} + +async fn read_limited_line( + reader: &mut BufReader, + line: &mut String, + limit: usize, +) -> anyhow::Result<()> +where + R: tokio::io::AsyncRead + Unpin, +{ + let len = reader.read_line(line).await?; + if len == 0 { + bail!("unexpected EOF while reading HTTP request"); + } + if line.len() > limit { + bail!("HTTP request line exceeds {limit} bytes"); + } + Ok(()) +} + +enum HttpBootRequest<'a> { + Get(&'a str), + Head(&'a str), + MethodNotAllowed, + BadRequest, +} + +fn parse_request_line(line: &str) -> anyhow::Result> { + let mut parts = line.trim_end_matches(['\r', '\n']).split_whitespace(); + let method = parts + .next() + .ok_or_else(|| anyhow::anyhow!("empty request"))?; + let target = parts + .next() + .ok_or_else(|| anyhow::anyhow!("missing target"))?; + let version = parts + .next() + .ok_or_else(|| anyhow::anyhow!("missing version"))?; + if !version.starts_with("HTTP/1.") { + return Ok(HttpBootRequest::BadRequest); + } + if parts.next().is_some() { + return Ok(HttpBootRequest::BadRequest); + } + + let path = target.split('?').next().unwrap_or(target); + match method { + "GET" => Ok(HttpBootRequest::Get(path)), + "HEAD" => Ok(HttpBootRequest::Head(path)), + _ => Ok(HttpBootRequest::MethodNotAllowed), + } +} + +async fn file_response(root_dir: &Path, request_path: &str, include_body: bool) -> Vec { + let Some(relative_path) = request_path.strip_prefix("/boot/") else { + return http_response( + "404 Not Found", + "text/plain", + b"not found".to_vec(), + include_body, + ); + }; + let relative_path = match normalize_relative_path(relative_path) { + Ok(path) => path, + Err(_) => { + return http_response( + "400 Bad Request", + "text/plain", + b"bad request".to_vec(), + include_body, + ); + } + }; + let disk_path = root_dir.join(relative_path); + let body = match fs::read(&disk_path).await { + Ok(body) => body, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => { + return http_response( + "404 Not Found", + "text/plain", + b"not found".to_vec(), + include_body, + ); + } + Err(_) => { + return http_response( + "500 Internal Server Error", + "text/plain", + b"internal server error".to_vec(), + include_body, + ); + } + }; + let content_type = mime_guess::from_path(&disk_path) + .first_or_octet_stream() + .to_string(); + http_response("200 OK", &content_type, body, include_body) +} + +fn http_response(status: &str, content_type: &str, body: Vec, include_body: bool) -> Vec { + let headers = format!( + "HTTP/1.1 {status}\r\nContent-Type: {content_type}\r\nContent-Length: {}\r\nConnection: close\r\n\r\n", + body.len() + ); + let mut response = headers.into_bytes(); + if include_body { + response.extend_from_slice(&body); + } + response +} diff --git a/ostool-server/src/lib.rs b/ostool-server/src/lib.rs index c5eb7e61..d62b70ca 100644 --- a/ostool-server/src/lib.rs +++ b/ostool-server/src/lib.rs @@ -17,11 +17,11 @@ pub mod web; pub use api::router::build_router; pub use config::{ - BoardConfig, BootConfig, BuiltinTftpConfig, CustomPowerManagement, PowerManagementConfig, - ProxyDhcpConfig, PxeProfile, SerialConfig, SerialPortKey, SerialPortKeyKind, ServerConfig, - SystemTftpdHpaConfig, TftpConfig, TftpNetworkConfig, UbootProfile, UefiBootArch, - UefiHttpProfile, UefiHttpStrategy, UploadLimitsConfig, VirtualPowerManagement, - ZhongshengRelayPowerManagement, + BoardConfig, BootConfig, BuiltinTftpConfig, CustomPowerManagement, HttpBootHttpsConfig, + PowerManagementConfig, ProxyDhcpConfig, PxeProfile, SerialConfig, SerialPortKey, + SerialPortKeyKind, ServerConfig, SystemTftpdHpaConfig, TftpConfig, TftpNetworkConfig, + UbootProfile, UefiBootArch, UefiHttpProfile, UefiHttpStrategy, UploadLimitsConfig, + VirtualPowerManagement, ZhongshengRelayPowerManagement, }; pub use dtb_store::{DtbFile, DtbStore}; pub use state::{AppState, BoardLeaseState, build_app_state}; diff --git a/ostool-server/src/main.rs b/ostool-server/src/main.rs index 189ef0b3..a03ef930 100644 --- a/ostool-server/src/main.rs +++ b/ostool-server/src/main.rs @@ -4,7 +4,9 @@ use anyhow::Context; use clap::Parser; use log::info; use ostool_server::{ - ServerConfig, build_app_state, build_router, proxy_dhcp, + ServerConfig, build_app_state, build_router, + http_boot::https::spawn_https_static_server, + proxy_dhcp, tftp::service::{BuiltinTftpManager, SystemTftpdHpaManager, TftpManager}, }; @@ -44,6 +46,8 @@ async fn main() -> anyhow::Result<()> { tftp_manager.reconcile().await?; } let _proxy_dhcp_task = proxy_dhcp::spawn_proxy_dhcp(state.clone()).await?; + let http_boot_config = state.config.read().await.http_boot.clone(); + let _http_boot_https_task = spawn_https_static_server(&http_boot_config).await?; let gc_state = state.clone(); tokio::spawn(async move { diff --git a/ostool-server/src/proxy_dhcp.rs b/ostool-server/src/proxy_dhcp.rs index 74f96a9d..9ca80c0f 100644 --- a/ostool-server/src/proxy_dhcp.rs +++ b/ostool-server/src/proxy_dhcp.rs @@ -211,7 +211,9 @@ fn select_board<'a>( fn proxy_server_ip(config: &ServerConfig) -> anyhow::Result { if let Some(base) = config.http_boot.public_base_url.as_deref() - && let Some(rest) = base.strip_prefix("http://") + && let Some(rest) = base + .strip_prefix("http://") + .or_else(|| base.strip_prefix("https://")) { let host = rest.split([':', '/']).next().unwrap_or_default(); if let Ok(ip) = host.parse() { diff --git a/ostool-server/tests/session_ws_lifecycle.rs b/ostool-server/tests/session_ws_lifecycle.rs index 9431dac4..eccea26c 100644 --- a/ostool-server/tests/session_ws_lifecycle.rs +++ b/ostool-server/tests/session_ws_lifecycle.rs @@ -115,6 +115,7 @@ fn spawn_test_server(root: &Path, serial_port: String) -> Result None: parser = argparse.ArgumentParser() parser.add_argument("--bind", default="0.0.0.0") @@ -14,7 +18,7 @@ def main() -> None: parser.add_argument("--key", required=True) args = parser.parse_args() - handler = partial(http.server.SimpleHTTPRequestHandler, directory=args.root) + handler = partial(Http11SimpleHTTPRequestHandler, directory=args.root) httpd = http.server.ThreadingHTTPServer((args.bind, args.port), handler) context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain(certfile=args.cert, keyfile=args.key) From fcdade00b457b897c55fe52d8d420231382fdf8d Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 18 May 2026 06:40:51 +0000 Subject: [PATCH 30/39] feat: add HTTP network warmup and retry logic for UEFI loader --- loongarch64-uefi-loader/src/abi.rs | 3 + loongarch64-uefi-loader/src/flow.rs | 187 +++++++++++++++++++++----- loongarch64-uefi-loader/src/loader.rs | 2 +- 3 files changed, 161 insertions(+), 31 deletions(-) diff --git a/loongarch64-uefi-loader/src/abi.rs b/loongarch64-uefi-loader/src/abi.rs index 8dcd4f55..83177b1d 100644 --- a/loongarch64-uefi-loader/src/abi.rs +++ b/loongarch64-uefi-loader/src/abi.rs @@ -19,6 +19,9 @@ const EFI_BUFFER_TOO_SMALL: EfiStatus = EfiStatus(EFI_ERROR_BIT | 5); const EFI_NOT_READY: EfiStatus = EfiStatus(EFI_ERROR_BIT | 6); const EFI_DEVICE_ERROR: EfiStatus = EfiStatus(EFI_ERROR_BIT | 7); const EFI_NOT_FOUND: EfiStatus = EfiStatus(EFI_ERROR_BIT | 14); +const EFI_NO_MAPPING: EfiStatus = EfiStatus(EFI_ERROR_BIT | 17); +const EFI_TIMEOUT: EfiStatus = EfiStatus(EFI_ERROR_BIT | 18); +const EFI_NOT_STARTED: EfiStatus = EfiStatus(EFI_ERROR_BIT | 19); const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 2; const EFI_LOADER_DATA: EfiMemoryType = 2; diff --git a/loongarch64-uefi-loader/src/flow.rs b/loongarch64-uefi-loader/src/flow.rs index 60fb79f1..82b14339 100644 --- a/loongarch64-uefi-loader/src/flow.rs +++ b/loongarch64-uefi-loader/src/flow.rs @@ -74,6 +74,141 @@ fn try_http_service_handle( status } +fn warm_up_http_network_child( + bs: *mut EfiBootServices, + binding: *mut EfiServiceBindingProtocol, + index: usize, +) -> EfiStatus { + write_ascii("http_network_warmup_index: "); + write_dec(index as u64); + write_ascii("\r\n"); + + let mut child = null_mut(); + let status = unsafe { ((*binding).create_child)(binding, &mut child) }; + write_status("http_network_warmup_create_child_status: ", status); + if status.is_error() || child.is_null() { + return if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }; + } + + let http = match open_protocol::(bs, child, &EFI_HTTP_PROTOCOL_GUID) { + Ok(http) => { + write_status("http_network_warmup_protocol_status: ", EFI_SUCCESS); + http + } + Err(status) => { + write_status("http_network_warmup_protocol_status: ", status); + unsafe { + ((*binding).destroy_child)(binding, child); + } + return status; + } + }; + + configure_tls_ca_on_handle(bs, child, "http_network_warmup_tls_config"); + let status = configure_http(http); + write_status("http_network_warmup_configure_status: ", status); + if !status.is_error() { + warm_up_http(bs, http); + } + + unsafe { + ((*binding).destroy_child)(binding, child); + } + status +} + +fn warm_up_http_network(bs: *mut EfiBootServices) -> EfiStatus { + let mut service_count = 0usize; + let mut service_handles = null_mut(); + let status = locate_protocol_handles( + bs, + &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, + &mut service_count, + &mut service_handles, + ); + write_status("http_network_warmup_service_status: ", status); + write_ascii("http_network_warmup_handle_count: "); + write_dec(service_count as u64); + write_ascii("\r\n"); + if status.is_error() || service_count == 0 || service_handles.is_null() { + return status; + } + + let mut result = EFI_NOT_FOUND; + let mut i = 0usize; + while i < service_count { + let handle = unsafe { *service_handles.add(i) }; + let binding = match open_protocol::( + bs, + handle, + &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, + ) { + Ok(binding) => binding, + Err(status) => { + write_status("http_network_warmup_binding_status: ", status); + i += 1; + continue; + } + }; + result = warm_up_http_network_child(bs, binding, i); + if !result.is_error() { + break; + } + i += 1; + } + + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } + result +} + +fn try_http_fallback(image: EfiHandle, bs: *mut EfiBootServices) -> EfiStatus { + let mut service_count = 0usize; + let mut service_handles = null_mut(); + let status = locate_protocol_handles( + bs, + &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, + &mut service_count, + &mut service_handles, + ); + write_status("http_service_binding_status: ", status); + write_ascii("http_service_binding_handle_count: "); + write_dec(service_count as u64); + write_ascii("\r\n"); + if status.is_error() || service_count == 0 || service_handles.is_null() { + return status; + } + + let mut result = EFI_NOT_FOUND; + let mut i = 0usize; + while i < service_count { + let handle = unsafe { *service_handles.add(i) }; + result = try_http_service_handle(image, bs, handle, i); + write_status("http_service_binding_try_status: ", result); + if !result.is_error() { + break; + } + i += 1; + } + unsafe { + ((*bs).free_pool)(service_handles as *mut c_void); + } + result +} + +fn stall_loader_retry(bs: *mut EfiBootServices) { + unsafe { + if let Some(stall) = (*bs).stall { + stall(3_000_000); + } + } +} + #[unsafe(no_mangle)] #[unsafe(link_section = ".text.efi_main")] extern "C" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTable) -> EfiStatus { @@ -117,39 +252,31 @@ extern "C" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTable) -> E configure_tls_ca(bs); run_tcp4_probe(bs); run_tls_clienthello_probe(bs); - let tcp4_tls_status = tcp4_tls_clienthello_probe(image, bs); - if !tcp4_tls_status.is_error() { - return EFI_SUCCESS; - } - let mut service_count = 0usize; - let mut service_handles = null_mut(); - let status = locate_protocol_handles( - bs, - &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, - &mut service_count, - &mut service_handles, - ); - write_status("http_service_binding_status: ", status); - write_ascii("http_service_binding_handle_count: "); - write_dec(service_count as u64); - write_ascii("\r\n"); - if status.is_error() || service_count == 0 || service_handles.is_null() { - return EFI_SUCCESS; - } + let mut attempt = 0usize; + while attempt < 3 { + write_ascii("loader_network_attempt: "); + write_dec(attempt as u64); + write_ascii("\r\n"); - let mut i = 0usize; - while i < service_count { - let handle = unsafe { *service_handles.add(i) }; - let status = try_http_service_handle(image, bs, handle, i); - write_status("http_service_binding_try_status: ", status); - if !status.is_error() { - break; + let warmup_status = warm_up_http_network(bs); + write_status("http_network_warmup_status: ", warmup_status); + + let tcp4_tls_status = tcp4_tls_clienthello_probe(image, bs); + write_status("loader_tcp4_tls_attempt_status: ", tcp4_tls_status); + if !tcp4_tls_status.is_error() { + return EFI_SUCCESS; } - i += 1; - } - unsafe { - ((*bs).free_pool)(service_handles as *mut c_void); + + let http_status = try_http_fallback(image, bs); + write_status("loader_http_fallback_status: ", http_status); + if !http_status.is_error() { + return EFI_SUCCESS; + } + + stall_loader_retry(bs); + attempt += 1; } + EFI_SUCCESS } diff --git a/loongarch64-uefi-loader/src/loader.rs b/loongarch64-uefi-loader/src/loader.rs index 7a51f599..3cf168d6 100644 --- a/loongarch64-uefi-loader/src/loader.rs +++ b/loongarch64-uefi-loader/src/loader.rs @@ -3,7 +3,7 @@ use core::ptr::{null_mut, read_volatile}; const OSTOOL_MANIFEST_URL: &str = env!("OSTOOL_MANIFEST_URL"); const OSTOOL_ENABLE_BOOT_JUMP: bool = cfg!(ostool_enable_boot_jump); -const OSTOOL_LOONGARCH64_LOADER_BUILD_ID: &str = "start46-strip-tls-plaintext-header"; +const OSTOOL_LOONGARCH64_LOADER_BUILD_ID: &str = "start48-in-loader-network-retry"; include!("abi.rs"); include!("console.rs"); From a19392841332491d7f467fc246c321643c9f1e3d Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 18 May 2026 07:11:24 +0000 Subject: [PATCH 31/39] feat: add TCP4 connect retry with network warmup and remove legacy C loader --- Cargo.lock | 460 ++++++------ loongarch64-uefi-loader/README.md | 16 +- loongarch64-uefi-loader/loader.c | 1042 --------------------------- loongarch64-uefi-loader/src/tcp4.rs | 264 +++---- ostool/src/run/httpboot.rs | 1 + picture/start.jpg | Bin 683866 -> 0 bytes scripts/https_static_server.py | 31 - 7 files changed, 327 insertions(+), 1487 deletions(-) delete mode 100644 loongarch64-uefi-loader/loader.c delete mode 100644 picture/start.jpg delete mode 100644 scripts/https_static_server.py diff --git a/Cargo.lock b/Cargo.lock index 8c190fa4..853bdcbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,9 +139,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.16.2" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" dependencies = [ "aws-lc-sys", "zeroize", @@ -149,9 +149,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.39.1" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" dependencies = [ "cc", "cmake", @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "axum" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core", "base64", @@ -188,7 +188,7 @@ dependencies = [ "sha1 0.10.6", "sync_wrapper", "tokio", - "tokio-tungstenite", + "tokio-tungstenite 0.29.0", "tower", "tower-layer", "tower-service", @@ -243,9 +243,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "bitvec" @@ -403,9 +403,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.58" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "jobserver", @@ -413,12 +413,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - [[package]] name = "cfg-if" version = "1.0.4" @@ -447,9 +441,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.0" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -469,9 +463,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.6.0" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", @@ -615,9 +609,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" [[package]] name = "crc32fast" @@ -634,7 +628,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "crossterm_winapi", "derive_more", "document-features", @@ -721,9 +715,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" [[package]] name = "deltae" @@ -780,9 +774,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer 0.12.0", "const-oid", @@ -923,9 +917,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "filedescriptor" @@ -940,13 +934,12 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.27" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", - "libredox", ] [[package]] @@ -1187,9 +1180,9 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "h2" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", @@ -1233,6 +1226,12 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + [[package]] name = "heck" version = "0.5.0" @@ -1302,9 +1301,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hybrid-array" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" dependencies = [ "typenum", ] @@ -1333,15 +1332,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.7" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http", "hyper", "hyper-util", "rustls", - "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", @@ -1503,9 +1501,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1513,12 +1511,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -1584,16 +1582,6 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1617,9 +1605,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" +checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d" dependencies = [ "jiff-static", "log", @@ -1630,9 +1618,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" +checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7" dependencies = [ "proc-macro2", "quote", @@ -1664,27 +1652,32 @@ dependencies = [ [[package]] name = "jni" -version = "0.21.1" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" dependencies = [ - "cesu8", "cfg-if", "combine", - "jni-sys 0.3.1", + "jni-macros", + "jni-sys", "log", - "thiserror 1.0.69", + "simd_cesu8", + "thiserror 2.0.18", "walkdir", - "windows-sys 0.45.0", + "windows-link", ] [[package]] -name = "jni-sys" -version = "0.3.1" +name = "jni-macros" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" dependencies = [ - "jni-sys 0.4.1", + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.117", ] [[package]] @@ -1718,9 +1711,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.94" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" +checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" dependencies = [ "cfg-if", "futures-util", @@ -1759,20 +1752,17 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.184" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libredox" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" +checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ - "bitflags 2.11.0", "libc", - "plain", - "redox_syscall 0.7.3", ] [[package]] @@ -1797,9 +1787,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.25" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52f4c29e2a68ac30c9087e1b772dc9f44a2b66ed44edf2266cf2be9b03dafc1" +checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" dependencies = [ "cc", "pkg-config", @@ -1812,7 +1802,7 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -1850,9 +1840,9 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" +checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" dependencies = [ "hashbrown 0.16.1", ] @@ -2020,7 +2010,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg-if", "cfg_aliases", "libc", @@ -2125,9 +2115,9 @@ dependencies = [ [[package]] name = "object" -version = "0.39.0" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63944c133d03f44e75866bbd160b95af0ec3f6a13d936d69d31c81078cbc5baf" +checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b" dependencies = [ "flate2", "memchr", @@ -2202,7 +2192,7 @@ dependencies = [ "thiserror 2.0.18", "tokio", "tokio-serial", - "tokio-tungstenite", + "tokio-tungstenite 0.28.0", "tokio-util", "toml", "trybuild", @@ -2239,7 +2229,7 @@ dependencies = [ "tokio-modbus", "tokio-rustls", "tokio-serial", - "tokio-tungstenite", + "tokio-tungstenite 0.28.0", "toml", "tower", "tower-http", @@ -2264,7 +2254,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link", ] @@ -2345,7 +2335,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -2378,15 +2368,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "portable-atomic" @@ -2396,9 +2380,9 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ "portable-atomic", ] @@ -2505,7 +2489,7 @@ dependencies = [ "bytes", "getrandom 0.3.4", "lru-slab", - "rand 0.9.2", + "rand 0.9.4", "ring", "rustc-hash", "rustls", @@ -2560,9 +2544,9 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -2571,9 +2555,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -2637,7 +2621,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "compact_str", "hashbrown 0.16.1", "indoc", @@ -2689,7 +2673,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "hashbrown 0.16.1", "indoc", "instability", @@ -2708,16 +2692,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.0", -] - -[[package]] -name = "redox_syscall" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" -dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -2791,9 +2766,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" +checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" dependencies = [ "base64", "bytes", @@ -2909,15 +2884,15 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.41.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ce901f9a19d251159075a4c37af514c3b8ef99c22e02dd8c19161cf397ee94a" +checksum = "0c5108e3d4d903e21aac27f12ba5377b6b34f9f44b325e4894c7924169d06995" dependencies = [ "arrayvec", "borsh", "bytes", "num-traits", - "rand 0.8.5", + "rand 0.8.6", "rkyv", "serde", "serde_json", @@ -2945,7 +2920,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys", @@ -2954,9 +2929,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.37" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "aws-lc-rs", "log", @@ -2982,9 +2957,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ "web-time", "zeroize", @@ -2992,9 +2967,9 @@ dependencies = [ [[package]] name = "rustls-platform-verifier" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" dependencies = [ "core-foundation 0.10.1", "core-foundation-sys", @@ -3019,9 +2994,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.10" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "aws-lc-rs", "ring", @@ -3037,9 +3012,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ruzstd" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ff0cc5e135c8870a775d3320910cd9b564ec036b4dc0b8741629020be63f01" +checksum = "a7c1c839d570d835527c9a5e4db7cb2198683a988cb9d7293fc8674e6bd58fc8" dependencies = [ "twox-hash", ] @@ -3111,7 +3086,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -3130,9 +3105,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" dependencies = [ "serde", "serde_core", @@ -3230,7 +3205,7 @@ version = "4.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4d91116f97173694f1642263b2ff837f80d933aa837e2314969f6728f661df3" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg-if", "core-foundation 0.10.1", "core-foundation-sys", @@ -3262,7 +3237,7 @@ checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" dependencies = [ "cfg-if", "cpufeatures 0.3.0", - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -3284,7 +3259,7 @@ checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", "cpufeatures 0.3.0", - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -3339,6 +3314,16 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + [[package]] name = "simdutf8" version = "0.1.5" @@ -3347,9 +3332,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "siphasher" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" [[package]] name = "slab" @@ -3466,7 +3451,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -3555,7 +3540,7 @@ checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7" dependencies = [ "anyhow", "base64", - "bitflags 2.11.0", + "bitflags 2.11.1", "fancy-regex", "filedescriptor", "finl_unicode", @@ -3683,9 +3668,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.50.0" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -3700,9 +3685,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -3784,7 +3769,19 @@ dependencies = [ "futures-util", "log", "tokio", - "tungstenite", + "tungstenite 0.28.0", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f72a05e828585856dacd553fba484c242c46e391fb0e58917c942ee9202915c" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.29.0", ] [[package]] @@ -3827,9 +3824,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.10+spec-1.1.0" +version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82418ca169e235e6c399a84e395ab6debeb3bc90edc959bf0f48647c6a32d1b" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ "indexmap", "toml_datetime", @@ -3870,11 +3867,11 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "68d6fdd9f81c2819c9a8b0e0cd91660e7746a8e6ea2ba7c6b2b057985f6bcb51" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytes", "futures-core", "futures-util", @@ -3883,7 +3880,6 @@ dependencies = [ "http-body-util", "http-range-header", "httpdate", - "iri-string", "mime", "mime_guess", "percent-encoding", @@ -3893,7 +3889,7 @@ dependencies = [ "tower", "tower-layer", "tower-service", - "tracing", + "url", ] [[package]] @@ -3960,12 +3956,28 @@ dependencies = [ "http", "httparse", "log", - "rand 0.9.2", + "rand 0.9.4", "sha1 0.10.6", "thiserror 2.0.18", "utf-8", ] +[[package]] +name = "tungstenite" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.9.4", + "sha1 0.10.6", + "thiserror 2.0.18", +] + [[package]] name = "twox-hash" version = "2.1.2" @@ -3974,9 +3986,9 @@ checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "uboot-shell" @@ -4136,9 +4148,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ "atomic", "getrandom 0.4.2", @@ -4201,11 +4213,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.57.1", ] [[package]] @@ -4214,14 +4226,14 @@ version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.51.0", ] [[package]] name = "wasm-bindgen" -version = "0.2.117" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" +checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" dependencies = [ "cfg-if", "once_cell", @@ -4232,9 +4244,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.67" +version = "0.4.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" +checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" dependencies = [ "js-sys", "wasm-bindgen", @@ -4242,9 +4254,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.117" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" +checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4252,9 +4264,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.117" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" +checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" dependencies = [ "bumpalo", "proc-macro2", @@ -4265,9 +4277,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.117" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" +checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" dependencies = [ "unicode-ident", ] @@ -4300,7 +4312,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "hashbrown 0.15.5", "indexmap", "semver", @@ -4308,9 +4320,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.94" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" +checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" dependencies = [ "js-sys", "wasm-bindgen", @@ -4328,18 +4340,18 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" dependencies = [ "rustls-pki-types", ] [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" dependencies = [ "rustls-pki-types", ] @@ -4517,15 +4529,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -4553,21 +4556,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -4601,12 +4589,6 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -4619,12 +4601,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -4637,12 +4613,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -4667,12 +4637,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -4685,12 +4649,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -4703,12 +4661,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -4721,12 +4673,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -4741,9 +4687,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] @@ -4757,6 +4703,12 @@ dependencies = [ "wit-bindgen-rust-macro", ] +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + [[package]] name = "wit-bindgen-core" version = "0.51.0" @@ -4806,7 +4758,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.0", + "bitflags 2.11.1", "indexmap", "log", "serde", @@ -4838,9 +4790,9 @@ dependencies = [ [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "wyz" @@ -4906,9 +4858,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] diff --git a/loongarch64-uefi-loader/README.md b/loongarch64-uefi-loader/README.md index 33332da9..4f261fb9 100644 --- a/loongarch64-uefi-loader/README.md +++ b/loongarch64-uefi-loader/README.md @@ -9,15 +9,13 @@ It intentionally does not use iPXE. The firmware starts: EFI/BOOT/BOOTLOONGARCH64.EFI ``` -The loader is implemented in Rust (`src/main.rs`). The previous C version is -kept as `loader.c` for reference while the board bring-up is still moving. - -The Rust loader then uses UEFI HTTP Protocol to download `manifest.json`, -downloads `kernel.bin` to `kernel_load_addr`, prints the entry plan, and keeps -the final jump behind `ENABLE_BOOT_JUMP=0` until the board-side observations are -stable. It currently matches the C bring-up path, including the TLS -Configuration probe and embedded temporary CA certificate used during HTTPS -validation. +The loader is implemented in Rust (`src/main.rs` and the modules under `src/`). +There is no C loader path in this directory. + +The Rust loader brings up serial logging, probes the firmware networking +protocols, downloads `manifest.json` and `kernel.bin` over HTTPS, places the +kernel at `kernel_load_addr`, prepares framebuffer boot info, and jumps to +`entry_point` when `ENABLE_BOOT_JUMP=1`. Build: diff --git a/loongarch64-uefi-loader/loader.c b/loongarch64-uefi-loader/loader.c deleted file mode 100644 index c463a51f..00000000 --- a/loongarch64-uefi-loader/loader.c +++ /dev/null @@ -1,1042 +0,0 @@ -#include -#include - -#ifndef OSTOOL_MANIFEST_URL -#define OSTOOL_MANIFEST_URL "http://10.3.10.229:2999/boot/boards/loongchip-httpboot-smoke/current/manifest.json" -#endif - -#ifndef OSTOOL_ENABLE_BOOT_JUMP -#define OSTOOL_ENABLE_BOOT_JUMP 0 -#endif - -typedef uint64_t efi_physical_address_t; -typedef uint64_t efi_virtual_address_t; -typedef void *efi_handle_t; -typedef void *efi_event_t; -typedef uint64_t efi_status_t; -typedef uint64_t efi_tpl_t; -typedef uint64_t efi_uintn_t; -typedef uint32_t efi_memory_type_t; -typedef uint32_t efi_allocate_type_t; -typedef uint32_t efi_locate_search_type_t; -typedef uint16_t efi_char16_t; - -#define EFI_SUCCESS 0 -#define EFI_ERROR_BIT (1ULL << 63) -#define EFI_LOAD_ERROR (EFI_ERROR_BIT | 1) -#define EFI_UNSUPPORTED (EFI_ERROR_BIT | 3) -#define EFI_BUFFER_TOO_SMALL (EFI_ERROR_BIT | 5) -#define EFI_NOT_READY (EFI_ERROR_BIT | 6) -#define EFI_DEVICE_ERROR (EFI_ERROR_BIT | 7) -#define EFI_NOT_FOUND (EFI_ERROR_BIT | 14) -#define EFI_ACCESS_DENIED (EFI_ERROR_BIT | 15) - -#define EFI_ALLOCATE_ADDRESS 0 -#define EFI_LOADER_DATA 2 -#define EFI_LOCATE_BY_PROTOCOL 2 -#define EVT_NOTIFY_SIGNAL 0x00000200U -#define TPL_CALLBACK 8 -#define EFI_PAGE_SIZE 4096 - -#define HTTP_VERSION_11 1 -#define HTTP_METHOD_GET 0 -#define HTTP_STATUS_200_OK 3 - -#define MANIFEST_MAX 4096 -#define URL16_MAX 1024 -#define KERNEL_CHUNK 16384 -#define MAX_KERNEL_SIZE (256U * 1024U * 1024U) -#define MEMORY_MAP_MAX 65536 -#define HTTP_POLL_LIMIT 1000000U - -typedef struct { - uint32_t data1; - uint16_t data2; - uint16_t data3; - uint8_t data4[8]; -} efi_guid_t; - -typedef struct { - uint64_t signature; - uint32_t revision; - uint32_t header_size; - uint32_t crc32; - uint32_t reserved; -} efi_table_header_t; - -typedef struct efi_simple_text_output_protocol efi_simple_text_output_protocol_t; -struct efi_simple_text_output_protocol { - void *reset; - efi_status_t (*output_string)(efi_simple_text_output_protocol_t *this, - const efi_char16_t *string); -}; - -typedef struct { - uint32_t type; - efi_physical_address_t physical_start; - efi_virtual_address_t virtual_start; - uint64_t number_of_pages; - uint64_t attribute; -} efi_memory_descriptor_t; - -typedef struct efi_boot_services efi_boot_services_t; -struct efi_boot_services { - efi_table_header_t hdr; - void *raise_tpl; - void *restore_tpl; - efi_status_t (*allocate_pages)(efi_allocate_type_t type, - efi_memory_type_t memory_type, - efi_uintn_t pages, - efi_physical_address_t *memory); - efi_status_t (*free_pages)(efi_physical_address_t memory, efi_uintn_t pages); - efi_status_t (*get_memory_map)(efi_uintn_t *memory_map_size, - efi_memory_descriptor_t *memory_map, - efi_uintn_t *map_key, - efi_uintn_t *descriptor_size, - uint32_t *descriptor_version); - efi_status_t (*allocate_pool)(efi_memory_type_t pool_type, - efi_uintn_t size, - void **buffer); - efi_status_t (*free_pool)(void *buffer); - efi_status_t (*create_event)(uint32_t type, - efi_tpl_t notify_tpl, - void (*notify_function)(efi_event_t event, void *context), - void *notify_context, - efi_event_t *event); - void *set_timer; - void *wait_for_event; - void *signal_event; - efi_status_t (*close_event)(efi_event_t event); - void *check_event; - void *install_protocol_interface; - void *reinstall_protocol_interface; - void *uninstall_protocol_interface; - efi_status_t (*handle_protocol)(efi_handle_t handle, - const efi_guid_t *protocol, - void **interface); - void *reserved; - void *register_protocol_notify; - void *locate_handle; - void *locate_device_path; - void *install_configuration_table; - void *load_image; - void *start_image; - void *exit; - void *unload_image; - efi_status_t (*exit_boot_services)(efi_handle_t image_handle, - efi_uintn_t map_key); - void *get_next_monotonic_count; - efi_status_t (*stall)(efi_uintn_t microseconds); - void *set_watchdog_timer; - void *connect_controller; - void *disconnect_controller; - void *open_protocol; - void *close_protocol; - void *open_protocol_information; - void *protocols_per_handle; - efi_status_t (*locate_handle_buffer)(efi_locate_search_type_t search_type, - const efi_guid_t *protocol, - void *search_key, - efi_uintn_t *no_handles, - efi_handle_t **buffer); -}; - -typedef struct { - efi_table_header_t hdr; - efi_char16_t *firmware_vendor; - uint32_t firmware_revision; - efi_handle_t console_in_handle; - void *con_in; - efi_handle_t console_out_handle; - efi_simple_text_output_protocol_t *con_out; - efi_handle_t standard_error_handle; - efi_simple_text_output_protocol_t *std_err; - void *runtime_services; - efi_boot_services_t *boot_services; -} efi_system_table_t; - -typedef struct efi_service_binding_protocol efi_service_binding_protocol_t; -struct efi_service_binding_protocol { - efi_status_t (*create_child)(efi_service_binding_protocol_t *this, - efi_handle_t *child_handle); - efi_status_t (*destroy_child)(efi_service_binding_protocol_t *this, - efi_handle_t child_handle); -}; - -typedef struct efi_http_protocol efi_http_protocol_t; -typedef struct efi_tls_configuration_protocol efi_tls_configuration_protocol_t; -typedef union { - void *ipv4_node; - void *ipv6_node; -} efi_http_config_access_point_t; - -typedef struct { - uint8_t use_default_address; - uint8_t local_address[4]; - uint8_t local_subnet[4]; - uint16_t local_port; -} efi_httpv4_access_point_t; - -typedef struct { - uint32_t http_version; - uint32_t timeout_millisec; - uint8_t local_address_is_ipv6; - uint8_t padding[7]; - efi_http_config_access_point_t access_point; -} efi_http_config_data_t; - -typedef struct { - uint32_t method; - efi_char16_t *url; -} efi_http_request_data_t; - -typedef struct { - uint32_t status_code; -} efi_http_response_data_t; - -typedef union { - efi_http_request_data_t *request; - efi_http_response_data_t *response; -} efi_http_message_data_t; - -typedef struct { - char *field_name; - char *field_value; -} efi_http_header_t; - -typedef struct { - efi_http_message_data_t data; - efi_uintn_t header_count; - efi_http_header_t *headers; - efi_uintn_t body_length; - void *body; -} efi_http_message_t; - -typedef struct { - efi_event_t event; - efi_status_t status; - efi_http_message_t *message; -} efi_http_token_t; - -struct efi_http_protocol { - void *get_mode_data; - efi_status_t (*configure)(efi_http_protocol_t *this, - efi_http_config_data_t *http_config_data); - efi_status_t (*request)(efi_http_protocol_t *this, efi_http_token_t *token); - void *cancel; - efi_status_t (*response)(efi_http_protocol_t *this, efi_http_token_t *token); - efi_status_t (*poll)(efi_http_protocol_t *this); -}; - -enum { - EFI_TLS_CONFIG_DATA_TYPE_HOST_PUBLIC_CERT = 0, - EFI_TLS_CONFIG_DATA_TYPE_HOST_PRIVATE_KEY = 1, - EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE = 2, - EFI_TLS_CONFIG_DATA_TYPE_CERT_REVOCATION_LIST = 3, -}; - -struct efi_tls_configuration_protocol { - efi_status_t (*set_data)(efi_tls_configuration_protocol_t *this, - uint32_t data_type, - void *data, - efi_uintn_t data_size); - efi_status_t (*get_data)(efi_tls_configuration_protocol_t *this, - uint32_t data_type, - void *data, - efi_uintn_t *data_size); -}; - -typedef struct { - char kernel_url[1024]; - uint64_t kernel_size; - uint64_t kernel_load_addr; - uint64_t entry_point; - char arch[32]; -} manifest_t; - -static const efi_guid_t efi_http_service_binding_protocol_guid = { - 0xbdc8e6af, 0xd9bc, 0x4379, {0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c} -}; - -static const efi_guid_t efi_http_protocol_guid = { - 0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b} -}; - -static const efi_guid_t efi_tls_service_binding_protocol_guid = { - 0x952cb795, 0xff36, 0x48cf, {0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d} -}; - -static const efi_guid_t efi_tls_configuration_protocol_guid = { - 0x1682fe44, 0xbd7a, 0x4407, {0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d} -}; - -static const efi_guid_t efi_tcp4_service_binding_protocol_guid = { - 0x00720665, 0x67eb, 0x4a99, {0xba, 0xf7, 0xd3, 0xc3, 0x3a, 0x1c, 0x7c, 0xc9} -}; - -static efi_simple_text_output_protocol_t *g_console; - -static char g_https_ca_pem[] = - "-----BEGIN CERTIFICATE-----\n" - "MIIDHjCCAgagAwIBAgIUBJubHQIousJm3ZT9sNPYq0u1AhwwDQYJKoZIhvcNAQEL\n" - "BQAwFjEUMBIGA1UEAwwLMTAuMy4xMC4yMjkwHhcNMjYwNTEzMDkxMTIwWhcNMjYw\n" - "NTIwMDkxMTIwWjAWMRQwEgYDVQQDDAsxMC4zLjEwLjIyOTCCASIwDQYJKoZIhvcN\n" - "AQEBBQADggEPADCCAQoCggEBALb3klUcff8fXYIcsgeQr1gs2rnwbOl/4Unwtulx\n" - "wG1K8joXYwWT4NP4XSOJy8aVuLk0FSd8VB29l6gjduSYzdC1CE9i3bzJnu4E96X/\n" - "EqRWP6QPkQJUizpH3qwxK1sDNJTmoAdq48v3cLgyyDdxzU/iVlWM51izk4njFMzZ\n" - "4PCLFfznANnj8o5diDCQ96uyKxmaXArIeDAAwcTSlJYc7QHWg6WEg+FQcn3TaMKJ\n" - "8rNELrKMrygc71ZdF9r6anud4YMouse6wJmEzGEVSCQ/y3dxd8gr1Ixq3DV9Yj9J\n" - "fZ57GWjWLTi1CWyMAAod8b6xr+o2yHRS2mGIfTEskTHTc+8CAwEAAaNkMGIwHQYD\n" - "VR0OBBYEFIimL7eY9PEocEUee1gz/YxTalmbMB8GA1UdIwQYMBaAFIimL7eY9PEo\n" - "cEUee1gz/YxTalmbMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0RBAgwBocECgMK5TAN\n" - "BgkqhkiG9w0BAQsFAAOCAQEAf1TkdDogQAYDgSUdraZ6WtOrD7MrLH69DZIcMrVf\n" - "GymOgar70uD9s1MEAwAsCgfqN8+kRcR/viWY8e86AzYVralqiLVs9tpR+vrnFejd\n" - "f9KLftc3owFwmiMLR5szwZMENOz2F+TJ8fNZBTXaJuITxrcIwuBym0FqL1pkN4hL\n" - "ikfU5paqfDst5LA/Wu/56XPtP8tFGh498jNsKlAumlQgaX0w+xxGiaGf1WkvTOP8\n" - "bVwyUYVeTIG2utpOKra0gkg42qcPdvRzZsT9REzlp2cxyBx5fkSmS0kXtqg4fT69\n" - "9/dZPxTWismXdZ4HN74kKak5tAB9CwKXvwaLRqOmXEg4hw==\n" - "-----END CERTIFICATE-----\n"; - -static size_t strlen8(const char *s) { - size_t len = 0; - while (s[len] != '\0') { - len++; - } - return len; -} - -static void memset8(void *dst, uint8_t value, size_t len) { - uint8_t *d = (uint8_t *)dst; - for (size_t i = 0; i < len; i++) { - d[i] = value; - } -} - -static int is_error(efi_status_t status) { - return (status & EFI_ERROR_BIT) != 0; -} - -static void write_ascii(const char *s) { - static efi_char16_t buf[256]; - if (!g_console) { - return; - } - while (*s) { - size_t n = 0; - while (s[n] && n + 1 < (sizeof(buf) / sizeof(buf[0]))) { - buf[n] = (uint8_t)s[n]; - n++; - } - buf[n] = 0; - g_console->output_string(g_console, buf); - s += n; - } -} - -static void write_hex64(uint64_t value) { - char out[17]; - for (int i = 0; i < 16; i++) { - uint8_t digit = (value >> ((15 - i) * 4)) & 0xf; - out[i] = (digit < 10) ? ('0' + digit) : ('a' + digit - 10); - } - out[16] = '\0'; - write_ascii(out); -} - -static void write_dec(uint64_t value) { - char out[32]; - size_t pos = sizeof(out); - out[--pos] = '\0'; - if (value == 0) { - out[--pos] = '0'; - } else { - while (value > 0 && pos > 0) { - out[--pos] = (char)('0' + (value % 10)); - value /= 10; - } - } - write_ascii(&out[pos]); -} - -static void write_status(const char *label, efi_status_t status) { - write_ascii(label); - write_ascii("0x"); - write_hex64(status); - write_ascii("\r\n"); -} - -static int write_utf16_url(const char *url, efi_char16_t *out, size_t cap) { - size_t len = strlen8(url); - if (len + 1 > cap) { - return -1; - } - for (size_t i = 0; i < len; i++) { - out[i] = (uint8_t)url[i]; - } - out[len] = 0; - return 0; -} - -static int write_https_probe_url(const char *url, efi_char16_t *out, size_t cap) { - const char http_prefix[] = "http://"; - const char https_prefix[] = "https://"; - for (size_t i = 0; i < sizeof(http_prefix) - 1; i++) { - if (url[i] != http_prefix[i]) { - return -1; - } - } - - size_t suffix_len = strlen8(url + sizeof(http_prefix) - 1); - if ((sizeof(https_prefix) - 1) + suffix_len + 1 > cap) { - return -1; - } - size_t pos = 0; - for (size_t i = 0; i < sizeof(https_prefix) - 1; i++) { - out[pos++] = (uint8_t)https_prefix[i]; - } - for (size_t i = 0; i < suffix_len; i++) { - out[pos++] = (uint8_t)url[(sizeof(http_prefix) - 1) + i]; - } - out[pos] = 0; - return 0; -} - -static void noop_event(efi_event_t event, void *context) { - (void)event; - (void)context; -} - -static efi_status_t poll_http(efi_http_protocol_t *http, efi_http_token_t *token) { - volatile efi_status_t *token_status = &token->status; - for (uint32_t i = 0; i < HTTP_POLL_LIMIT; i++) { - if (*token_status != EFI_NOT_READY) { - return *token_status; - } - http->poll(http); - } - return *token_status; -} - -static void warm_up_http(efi_boot_services_t *bs, efi_http_protocol_t *http) { - efi_status_t last_poll = EFI_NOT_READY; - for (uint32_t i = 0; i < 20; i++) { - if (bs->stall) { - bs->stall(100000); - } - last_poll = http->poll(http); - } - write_status("http_post_configure_poll_status: ", last_poll); -} - -static efi_status_t locate_protocol_handles(efi_boot_services_t *bs, - const efi_guid_t *guid, - efi_uintn_t *count, - efi_handle_t **handles) { - *count = 0; - *handles = 0; - return bs->locate_handle_buffer(EFI_LOCATE_BY_PROTOCOL, guid, 0, count, handles); -} - -static void print_protocol_handle_count(efi_boot_services_t *bs, - const char *label, - const efi_guid_t *guid) { - efi_uintn_t count = 0; - efi_handle_t *handles = 0; - efi_status_t status = locate_protocol_handles(bs, guid, &count, &handles); - write_ascii(label); - write_ascii("_status: "); - write_ascii("0x"); - write_hex64(status); - write_ascii("\r\n"); - write_ascii(label); - write_ascii("_handle_count: "); - write_dec(count); - write_ascii("\r\n"); - if (!is_error(status) && handles) { - bs->free_pool(handles); - } -} - -static void configure_tls_ca(efi_boot_services_t *bs) { - efi_uintn_t service_count = 0; - efi_handle_t *service_handles = 0; - efi_status_t status = locate_protocol_handles(bs, - &efi_tls_service_binding_protocol_guid, - &service_count, - &service_handles); - write_status("tls_config_service_status: ", status); - write_ascii("tls_config_service_handle_count: "); - write_dec(service_count); - write_ascii("\r\n"); - if (is_error(status) || service_count == 0 || !service_handles) { - return; - } - - efi_service_binding_protocol_t *binding = 0; - status = bs->handle_protocol(service_handles[0], - &efi_tls_service_binding_protocol_guid, - (void **)&binding); - write_status("tls_config_binding_open_status: ", status); - if (is_error(status) || !binding) { - bs->free_pool(service_handles); - return; - } - - efi_handle_t child = 0; - status = binding->create_child(binding, &child); - write_status("tls_config_create_child_status: ", status); - if (is_error(status) || !child) { - bs->free_pool(service_handles); - return; - } - - efi_tls_configuration_protocol_t *tls_config = 0; - status = bs->handle_protocol(child, - &efi_tls_configuration_protocol_guid, - (void **)&tls_config); - write_status("tls_config_protocol_status: ", status); - if (!is_error(status) && tls_config) { - efi_uintn_t ca_size = 0; - efi_status_t get_status = tls_config->get_data(tls_config, - EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, - 0, - &ca_size); - write_status("tls_config_get_ca_status: ", get_status); - write_ascii("tls_config_get_ca_size: "); - write_dec(ca_size); - write_ascii("\r\n"); - - status = tls_config->set_data(tls_config, - EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, - g_https_ca_pem, - (efi_uintn_t)strlen8(g_https_ca_pem)); - write_status("tls_config_set_ca_status: ", status); - - ca_size = 0; - get_status = tls_config->get_data(tls_config, - EFI_TLS_CONFIG_DATA_TYPE_CA_CERTIFICATE, - 0, - &ca_size); - write_status("tls_config_get_ca_after_status: ", get_status); - write_ascii("tls_config_get_ca_after_size: "); - write_dec(ca_size); - write_ascii("\r\n"); - } - - status = binding->destroy_child(binding, child); - write_status("tls_config_destroy_child_status: ", status); - bs->free_pool(service_handles); -} - -static efi_status_t configure_http(efi_http_protocol_t *http) { - static efi_httpv4_access_point_t ipv4; - static efi_http_config_data_t config; - memset8(&ipv4, 0, sizeof(ipv4)); - memset8(&config, 0, sizeof(config)); - ipv4.use_default_address = 1; - config.http_version = HTTP_VERSION_11; - config.timeout_millisec = 0; - config.local_address_is_ipv6 = 0; - config.access_point.ipv4_node = &ipv4; - return http->configure(http, &config); -} - -static efi_status_t http_request(efi_boot_services_t *bs, - efi_http_protocol_t *http, - const char *url, - const char *label) { - static efi_char16_t url16[URL16_MAX]; - if (write_utf16_url(url, url16, URL16_MAX) != 0) { - return EFI_BUFFER_TOO_SMALL; - } - - efi_event_t event = 0; - efi_status_t status = bs->create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, noop_event, 0, &event); - write_ascii(label); - write_ascii("_request_event_status: "); - write_ascii("0x"); - write_hex64(status); - write_ascii("\r\n"); - if (is_error(status)) { - return status; - } - - efi_http_request_data_t request_data; - request_data.method = HTTP_METHOD_GET; - request_data.url = url16; - efi_http_message_t message; - memset8(&message, 0, sizeof(message)); - message.data.request = &request_data; - efi_http_token_t token; - token.event = event; - token.status = EFI_NOT_READY; - token.message = &message; - - efi_status_t submit_status = http->request(http, &token); - write_ascii(label); - write_ascii("_request_submit_status: "); - write_ascii("0x"); - write_hex64(submit_status); - write_ascii("\r\n"); - status = submit_status; - if (!is_error(submit_status)) { - status = poll_http(http, &token); - } - write_ascii(label); - write_ascii("_request_token_status: "); - write_ascii("0x"); - write_hex64(token.status); - write_ascii("\r\n"); - bs->close_event(event); - return status; -} - -static efi_status_t https_request_probe(efi_boot_services_t *bs, - efi_http_protocol_t *http, - const char *url) { - static efi_char16_t url16[URL16_MAX]; - if (write_https_probe_url(url, url16, URL16_MAX) != 0) { - write_ascii("https_probe_url_status: unavailable\r\n"); - return EFI_UNSUPPORTED; - } - - efi_event_t event = 0; - efi_status_t status = bs->create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, noop_event, 0, &event); - write_status("https_probe_event_status: ", status); - if (is_error(status)) { - return status; - } - - efi_http_request_data_t request_data; - request_data.method = HTTP_METHOD_GET; - request_data.url = url16; - efi_http_message_t message; - memset8(&message, 0, sizeof(message)); - message.data.request = &request_data; - efi_http_token_t token; - token.event = event; - token.status = EFI_NOT_READY; - token.message = &message; - - efi_status_t submit_status = http->request(http, &token); - write_status("https_probe_submit_status: ", submit_status); - write_status("https_probe_token_status: ", token.status); - bs->close_event(event); - return submit_status; -} - -static efi_status_t http_response(efi_boot_services_t *bs, - efi_http_protocol_t *http, - void *body, - size_t *body_len, - uint32_t *http_status) { - efi_event_t event = 0; - efi_status_t status = bs->create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, noop_event, 0, &event); - if (is_error(status)) { - return status; - } - - efi_http_response_data_t response_data; - response_data.status_code = 0; - efi_http_message_t message; - memset8(&message, 0, sizeof(message)); - message.data.response = &response_data; - message.body_length = *body_len; - message.body = body; - - efi_http_token_t token; - token.event = event; - token.status = EFI_NOT_READY; - token.message = &message; - - status = http->response(http, &token); - if (!is_error(status)) { - status = poll_http(http, &token); - } - *body_len = message.body_length; - *http_status = response_data.status_code; - if (message.headers) { - bs->free_pool(message.headers); - } - bs->close_event(event); - return status; -} - -static const char *find_key(const char *json, const char *key) { - size_t key_len = strlen8(key); - for (const char *p = json; *p; p++) { - if (*p != '"') { - continue; - } - size_t i = 0; - while (i < key_len && p[1 + i] == key[i]) { - i++; - } - if (i == key_len && p[1 + i] == '"') { - const char *q = p + 2 + key_len; - while (*q == ' ' || *q == '\r' || *q == '\n' || *q == '\t') { - q++; - } - if (*q == ':') { - return q + 1; - } - } - } - return 0; -} - -static int json_string(const char *json, const char *key, char *out, size_t cap) { - const char *p = find_key(json, key); - if (!p) { - return -1; - } - while (*p == ' ' || *p == '\r' || *p == '\n' || *p == '\t') { - p++; - } - if (*p != '"') { - return -1; - } - p++; - size_t n = 0; - while (*p && *p != '"') { - if (*p == '\\' || n + 1 >= cap) { - return -1; - } - out[n++] = *p++; - } - if (*p != '"') { - return -1; - } - out[n] = '\0'; - return 0; -} - -static int parse_u64(const char *s, uint64_t *out) { - uint64_t value = 0; - int radix = 10; - int saw = 0; - if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { - radix = 16; - s += 2; - } - while (*s) { - if (*s == '_') { - s++; - continue; - } - uint8_t digit; - if (*s >= '0' && *s <= '9') { - digit = (uint8_t)(*s - '0'); - } else if (*s >= 'a' && *s <= 'f') { - digit = (uint8_t)(*s - 'a' + 10); - } else if (*s >= 'A' && *s <= 'F') { - digit = (uint8_t)(*s - 'A' + 10); - } else { - break; - } - if (digit >= radix) { - return -1; - } - value = value * (uint64_t)radix + digit; - saw = 1; - s++; - } - if (!saw) { - return -1; - } - *out = value; - return 0; -} - -static int json_u64(const char *json, const char *key, uint64_t *out) { - const char *p = find_key(json, key); - if (!p) { - return -1; - } - while (*p == ' ' || *p == '\r' || *p == '\n' || *p == '\t') { - p++; - } - return parse_u64(p, out); -} - -static int json_addr_string(const char *json, const char *key, uint64_t *out) { - char buf[64]; - if (json_string(json, key, buf, sizeof(buf)) != 0) { - return -1; - } - return parse_u64(buf, out); -} - -static int parse_manifest(const char *json, manifest_t *manifest) { - if (json_string(json, "kernel_url", manifest->kernel_url, sizeof(manifest->kernel_url)) != 0) { - return -1; - } - if (json_u64(json, "kernel_size", &manifest->kernel_size) != 0) { - return -1; - } - if (json_addr_string(json, "kernel_load_addr", &manifest->kernel_load_addr) != 0) { - return -1; - } - if (json_addr_string(json, "entry_point", &manifest->entry_point) != 0) { - return -1; - } - if (json_string(json, "arch", manifest->arch, sizeof(manifest->arch)) != 0) { - return -1; - } - return 0; -} - -static efi_uintn_t page_count(uint64_t addr, uint64_t size) { - (void)addr; - return (efi_uintn_t)((size + EFI_PAGE_SIZE - 1) / EFI_PAGE_SIZE); -} - -static efi_status_t download_kernel(efi_boot_services_t *bs, - efi_http_protocol_t *http, - const manifest_t *manifest, - efi_uintn_t *pages_out) { - if (manifest->kernel_size == 0 || manifest->kernel_size > MAX_KERNEL_SIZE) { - return EFI_UNSUPPORTED; - } - if ((manifest->kernel_load_addr % EFI_PAGE_SIZE) != 0) { - return EFI_UNSUPPORTED; - } - - efi_uintn_t pages = page_count(manifest->kernel_load_addr, manifest->kernel_size); - efi_physical_address_t target = manifest->kernel_load_addr; - efi_status_t status = bs->allocate_pages(EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, pages, &target); - write_status("kernel_allocate_pages_status: ", status); - write_ascii("kernel_target_addr: 0x"); - write_hex64(target); - write_ascii("\r\n"); - if (is_error(status) || target != manifest->kernel_load_addr) { - return status; - } - - status = http_request(bs, http, manifest->kernel_url, "kernel"); - write_status("kernel_request_completion: ", status); - if (is_error(status)) { - bs->free_pages(target, pages); - return status; - } - - uint64_t downloaded = 0; - uint32_t checksum = 0; - while (downloaded < manifest->kernel_size) { - size_t remaining = (size_t)(manifest->kernel_size - downloaded); - size_t body_len = remaining < KERNEL_CHUNK ? remaining : KERNEL_CHUNK; - uint32_t http_status = 0; - uint8_t *dst = (uint8_t *)(uintptr_t)(manifest->kernel_load_addr + downloaded); - status = http_response(bs, http, dst, &body_len, &http_status); - if (is_error(status) || http_status != HTTP_STATUS_200_OK || body_len == 0) { - write_status("kernel_response_completion: ", status); - write_ascii("kernel_response_status_enum: "); - write_dec(http_status); - write_ascii("\r\n"); - bs->free_pages(target, pages); - return is_error(status) ? status : EFI_DEVICE_ERROR; - } - for (size_t i = 0; i < body_len; i++) { - checksum += dst[i]; - } - downloaded += body_len; - } - - write_ascii("kernel_downloaded_size: "); - write_dec(downloaded); - write_ascii("\r\n"); - write_ascii("kernel_expected_size: "); - write_dec(manifest->kernel_size); - write_ascii("\r\n"); - write_ascii("kernel_checksum32: 0x"); - write_hex64(checksum); - write_ascii("\r\n"); - *pages_out = pages; - return EFI_SUCCESS; -} - -static efi_status_t print_memory_map(efi_boot_services_t *bs, efi_uintn_t *map_key_out) { - static uint8_t memory_map[MEMORY_MAP_MAX]; - efi_uintn_t map_size = sizeof(memory_map); - efi_uintn_t descriptor_size = 0; - uint32_t descriptor_version = 0; - efi_status_t status = bs->get_memory_map(&map_size, - (efi_memory_descriptor_t *)memory_map, - map_key_out, - &descriptor_size, - &descriptor_version); - write_status("memory_map_status: ", status); - write_ascii("memory_map_size: "); - write_dec(map_size); - write_ascii("\r\n"); - write_ascii("memory_map_key: "); - write_dec(*map_key_out); - write_ascii("\r\n"); - write_ascii("memory_map_descriptor_size: "); - write_dec(descriptor_size); - write_ascii("\r\n"); - return status; -} - -static void call_kernel(uint64_t entry_point) { - void (*entry)(void) = (void (*)(void))(uintptr_t)entry_point; - entry(); - for (;;) { - } -} - -static efi_status_t try_http_service_handle(efi_handle_t image, - efi_boot_services_t *bs, - efi_handle_t service_handle, - efi_uintn_t index) { - write_ascii("http_service_binding_try_index: "); - write_dec(index); - write_ascii("\r\n"); - efi_service_binding_protocol_t *binding = 0; - efi_status_t status = bs->handle_protocol(service_handle, - &efi_http_service_binding_protocol_guid, - (void **)&binding); - write_status("http_service_binding_open_status: ", status); - if (is_error(status) || !binding) { - return is_error(status) ? status : EFI_UNSUPPORTED; - } - - efi_handle_t child = 0; - status = binding->create_child(binding, &child); - write_status("http_create_child_status: ", status); - if (is_error(status) || !child) { - return is_error(status) ? status : EFI_UNSUPPORTED; - } - - efi_http_protocol_t *http = 0; - status = bs->handle_protocol(child, &efi_http_protocol_guid, (void **)&http); - write_status("http_child_protocol_status: ", status); - if (is_error(status) || !http) { - binding->destroy_child(binding, child); - return is_error(status) ? status : EFI_UNSUPPORTED; - } - - status = configure_http(http); - write_status("http_configure_status: ", status); - if (is_error(status)) { - binding->destroy_child(binding, child); - return status; - } - warm_up_http(bs, http); - - static char manifest_body[MANIFEST_MAX + 1]; - status = http_request(bs, http, OSTOOL_MANIFEST_URL, "manifest"); - write_status("manifest_request_completion: ", status); - if (is_error(status)) { - if (status == EFI_ACCESS_DENIED) { - https_request_probe(bs, http, OSTOOL_MANIFEST_URL); - } - binding->destroy_child(binding, child); - return status; - } - - size_t body_len = MANIFEST_MAX; - uint32_t http_status = 0; - status = http_response(bs, http, manifest_body, &body_len, &http_status); - write_status("manifest_response_completion: ", status); - write_ascii("manifest_response_status_enum: "); - write_dec(http_status); - write_ascii("\r\n"); - write_ascii("manifest_response_body_length: "); - write_dec(body_len); - write_ascii("\r\n"); - if (is_error(status) || http_status != HTTP_STATUS_200_OK || body_len >= sizeof(manifest_body)) { - binding->destroy_child(binding, child); - return is_error(status) ? status : EFI_DEVICE_ERROR; - } - manifest_body[body_len] = '\0'; - - manifest_t manifest; - memset8(&manifest, 0, sizeof(manifest)); - if (parse_manifest(manifest_body, &manifest) != 0) { - write_ascii("manifest_parse_failed\r\n"); - binding->destroy_child(binding, child); - return EFI_DEVICE_ERROR; - } - - write_ascii("manifest_arch: "); - write_ascii(manifest.arch); - write_ascii("\r\n"); - write_ascii("manifest_kernel_url: "); - write_ascii(manifest.kernel_url); - write_ascii("\r\n"); - write_ascii("manifest_kernel_size: "); - write_dec(manifest.kernel_size); - write_ascii("\r\n"); - write_ascii("manifest_kernel_load_addr: 0x"); - write_hex64(manifest.kernel_load_addr); - write_ascii("\r\n"); - write_ascii("manifest_entry_point: 0x"); - write_hex64(manifest.entry_point); - write_ascii("\r\n"); - - efi_uintn_t kernel_pages = 0; - status = download_kernel(bs, http, &manifest, &kernel_pages); - write_status("kernel_download_status: ", status); - if (is_error(status)) { - binding->destroy_child(binding, child); - return status; - } - - efi_uintn_t map_key = 0; - status = print_memory_map(bs, &map_key); - write_ascii("boot_jump_enabled: "); - write_ascii(OSTOOL_ENABLE_BOOT_JUMP ? "yes\r\n" : "no\r\n"); - if (!OSTOOL_ENABLE_BOOT_JUMP || is_error(status)) { - write_ascii("jump_skipped: boot jump disabled\r\n"); - binding->destroy_child(binding, child); - return EFI_SUCCESS; - } - - status = bs->exit_boot_services(image, map_key); - if (!is_error(status)) { - call_kernel(manifest.entry_point); - } - write_status("exit_boot_services_status: ", status); - write_ascii("jump_failed\r\n"); - (void)kernel_pages; - binding->destroy_child(binding, child); - return EFI_SUCCESS; -} - -efi_status_t efi_main(efi_handle_t image, efi_system_table_t *system_table) { - g_console = system_table ? system_table->con_out : 0; - write_ascii("ostool LoongArch64 UEFI loader\r\n"); - write_ascii("manifest_url: "); - write_ascii(OSTOOL_MANIFEST_URL); - write_ascii("\r\n"); - - efi_boot_services_t *bs = system_table->boot_services; - print_protocol_handle_count(bs, "tls_service_binding", &efi_tls_service_binding_protocol_guid); - print_protocol_handle_count(bs, "tcp4_service_binding", &efi_tcp4_service_binding_protocol_guid); - configure_tls_ca(bs); - - efi_uintn_t service_count = 0; - efi_handle_t *service_handles = 0; - efi_status_t status = locate_protocol_handles(bs, - &efi_http_service_binding_protocol_guid, - &service_count, - &service_handles); - write_status("http_service_binding_status: ", status); - write_ascii("http_service_binding_handle_count: "); - write_dec(service_count); - write_ascii("\r\n"); - if (is_error(status) || service_count == 0 || !service_handles) { - return EFI_SUCCESS; - } - - for (efi_uintn_t i = 0; i < service_count; i++) { - status = try_http_service_handle(image, bs, service_handles[i], i); - write_status("http_service_binding_try_status: ", status); - if (!is_error(status)) { - break; - } - } - bs->free_pool(service_handles); - return EFI_SUCCESS; -} diff --git a/loongarch64-uefi-loader/src/tcp4.rs b/loongarch64-uefi-loader/src/tcp4.rs index 12224690..35984198 100644 --- a/loongarch64-uefi-loader/src/tcp4.rs +++ b/loongarch64-uefi-loader/src/tcp4.rs @@ -1,4 +1,6 @@ const KERNEL_TRACE_RECORDS: bool = false; +const TCP4_CONNECT_RETRIES: usize = 6; +const TCP4_CONNECT_RETRY_DELAY_US: usize = 1_000_000; fn poll_tcp4(tcp4: *mut EfiTcp4Protocol, token: *const EfiTcp4CompletionToken) -> EfiStatus { let mut i = 0usize; @@ -1246,39 +1248,15 @@ fn close_tcp4_child( } } -fn connect_tcp4_child( - bs: *mut EfiBootServices, - tcp_binding: *mut EfiServiceBindingProtocol, - out_child: &mut EfiHandle, - label: &str, -) -> Result<*mut EfiTcp4Protocol, EfiStatus> { - *out_child = null_mut(); - let status = unsafe { ((*tcp_binding).create_child)(tcp_binding, out_child) }; - write_prefixed_status(label, "_tcp_create_child_status", status); - if status.is_error() || (*out_child).is_null() { - return Err(if status.is_error() { - status - } else { - EFI_UNSUPPORTED - }); - } - - let tcp4 = match open_protocol::(bs, *out_child, &EFI_TCP4_PROTOCOL_GUID) { - Ok(tcp4) => { - write_prefixed_status(label, "_tcp_protocol_status", EFI_SUCCESS); - tcp4 - } - Err(status) => { - write_prefixed_status(label, "_tcp_protocol_status", status); - unsafe { - ((*tcp_binding).destroy_child)(tcp_binding, *out_child); - } - *out_child = null_mut(); - return Err(status); - } - }; +fn tcp4_network_wait_status(status: EfiStatus) -> bool { + status == EFI_NO_MAPPING + || status == EFI_NOT_READY + || status == EFI_NOT_STARTED + || status == EFI_TIMEOUT +} - let mut config = EfiTcp4ConfigData { +fn make_tcp4_config(remote: [u8; 4], port: u16) -> EfiTcp4ConfigData { + EfiTcp4ConfigData { type_of_service: 0, time_to_live: 64, access_point: EfiTcp4AccessPoint { @@ -1286,8 +1264,8 @@ fn connect_tcp4_child( station_address: [0; 4], subnet_mask: [0; 4], station_port: 0, - remote_address: [10, 3, 10, 229], - remote_port: 3443, + remote_address: remote, + remote_port: port, active_flag: 1, }, control_option: EfiTcp4Option { @@ -1307,15 +1285,29 @@ fn connect_tcp4_child( enable_selective_ack: 0, enable_path_mtu_discovery: 0, }, - }; + } +} + +fn stall_tcp4_connect_retry(bs: *mut EfiBootServices) { + unsafe { + if let Some(stall) = (*bs).stall { + stall(TCP4_CONNECT_RETRY_DELAY_US); + } + } +} + +fn tcp4_connect_once_with_config( + bs: *mut EfiBootServices, + tcp4: *mut EfiTcp4Protocol, + remote: [u8; 4], + port: u16, + label: &str, +) -> EfiStatus { + let mut config = make_tcp4_config(remote, port); let status = unsafe { ((*tcp4).configure)(tcp4, &mut config) }; write_prefixed_status(label, "_tcp_configure_status", status); if status.is_error() { - unsafe { - ((*tcp_binding).destroy_child)(tcp_binding, *out_child); - } - *out_child = null_mut(); - return Err(status); + return status; } let mut connect_event = null_mut(); @@ -1332,10 +1324,8 @@ fn connect_tcp4_child( if status.is_error() { unsafe { ((*tcp4).configure)(tcp4, null_mut()); - ((*tcp_binding).destroy_child)(tcp_binding, *out_child); } - *out_child = null_mut(); - return Err(status); + return status; } let mut connect_token = EfiTcp4ConnectionToken { @@ -1352,16 +1342,89 @@ fn connect_tcp4_child( poll_tcp4(tcp4, &connect_token.completion_token) }; write_prefixed_status(label, "_connect_completion", connect_status); + write_prefixed_status( + label, + "_connect_token_status", + connect_token.completion_token.status, + ); unsafe { ((*bs).close_event)(connect_event); } + if connect_status.is_error() { unsafe { ((*tcp4).configure)(tcp4, null_mut()); + } + } + connect_status +} + +fn tcp4_connect_with_network_retry( + bs: *mut EfiBootServices, + tcp4: *mut EfiTcp4Protocol, + remote: [u8; 4], + port: u16, + label: &str, +) -> EfiStatus { + let mut attempt = 0usize; + let mut last_status = EFI_NOT_READY; + while attempt < TCP4_CONNECT_RETRIES { + write_ascii(label); + write_ascii("_connect_attempt: "); + write_dec(attempt as u64); + write_ascii("\r\n"); + + last_status = tcp4_connect_once_with_config(bs, tcp4, remote, port, label); + if !last_status.is_error() || !tcp4_network_wait_status(last_status) { + return last_status; + } + + write_prefixed_status(label, "_connect_wait_status", last_status); + stall_tcp4_connect_retry(bs); + attempt += 1; + } + last_status +} + +fn connect_tcp4_child( + bs: *mut EfiBootServices, + tcp_binding: *mut EfiServiceBindingProtocol, + out_child: &mut EfiHandle, + label: &str, +) -> Result<*mut EfiTcp4Protocol, EfiStatus> { + *out_child = null_mut(); + let status = unsafe { ((*tcp_binding).create_child)(tcp_binding, out_child) }; + write_prefixed_status(label, "_tcp_create_child_status", status); + if status.is_error() || (*out_child).is_null() { + return Err(if status.is_error() { + status + } else { + EFI_UNSUPPORTED + }); + } + + let tcp4 = match open_protocol::(bs, *out_child, &EFI_TCP4_PROTOCOL_GUID) { + Ok(tcp4) => { + write_prefixed_status(label, "_tcp_protocol_status", EFI_SUCCESS); + tcp4 + } + Err(status) => { + write_prefixed_status(label, "_tcp_protocol_status", status); + unsafe { + ((*tcp_binding).destroy_child)(tcp_binding, *out_child); + } + *out_child = null_mut(); + return Err(status); + } + }; + + let status = tcp4_connect_with_network_retry(bs, tcp4, [10, 3, 10, 229], 3443, label); + if status.is_error() { + unsafe { ((*tcp_binding).destroy_child)(tcp_binding, *out_child); } *out_child = null_mut(); - return Err(connect_status); + return Err(status); } Ok(tcp4) @@ -1837,30 +1900,10 @@ fn tcp4_tls_clienthello_probe(image: EfiHandle, bs: *mut EfiBootServices) -> Efi }; let mut tcp_child = null_mut(); - let status = unsafe { ((*tcp_binding).create_child)(tcp_binding, &mut tcp_child) }; - write_status("tcp4_tls_probe_tcp_create_child_status: ", status); - if status.is_error() || tcp_child.is_null() { - unsafe { - ((*bs).free_pool)(tcp_service_handles as *mut c_void); - ((*tls_binding).destroy_child)(tls_binding, tls_child); - ((*bs).free_pool)(tls_service_handles as *mut c_void); - } - return if status.is_error() { - status - } else { - EFI_UNSUPPORTED - }; - } - - let tcp4 = match open_protocol::(bs, tcp_child, &EFI_TCP4_PROTOCOL_GUID) { - Ok(tcp4) => { - write_status("tcp4_tls_probe_tcp_protocol_status: ", EFI_SUCCESS); - tcp4 - } + let tcp4 = match connect_tcp4_child(bs, tcp_binding, &mut tcp_child, "tcp4_tls_probe") { + Ok(tcp4) => tcp4, Err(status) => { - write_status("tcp4_tls_probe_tcp_protocol_status: ", status); unsafe { - ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); ((*bs).free_pool)(tcp_service_handles as *mut c_void); ((*tls_binding).destroy_child)(tls_binding, tls_child); ((*bs).free_pool)(tls_service_handles as *mut c_void); @@ -1868,97 +1911,16 @@ fn tcp4_tls_clienthello_probe(image: EfiHandle, bs: *mut EfiBootServices) -> Efi return status; } }; + write_status("tcp4_tls_probe_tcp_configure_status: ", EFI_SUCCESS); + write_status("tcp4_tls_probe_connect_completion: ", EFI_SUCCESS); - let mut config = EfiTcp4ConfigData { - type_of_service: 0, - time_to_live: 64, - access_point: EfiTcp4AccessPoint { - use_default_address: 1, - station_address: [0; 4], - subnet_mask: [0; 4], - station_port: 0, - remote_address: [10, 3, 10, 229], - remote_port: 3443, - active_flag: 1, - }, - control_option: EfiTcp4Option { - receive_buffer_size: 0, - send_buffer_size: 0, - max_syn_back_log: 0, - connection_timeout: 0, - data_retries: 0, - fin_timeout: 0, - time_wait_timeout: 0, - keep_alive_probes: 0, - keep_alive_time: 0, - keep_alive_interval: 0, - enable_nagle: 0, - enable_time_stamp: 0, - enable_window_scaling: 0, - enable_selective_ack: 0, - enable_path_mtu_discovery: 0, - }, - }; - let status = unsafe { ((*tcp4).configure)(tcp4, &mut config) }; - write_status("tcp4_tls_probe_tcp_configure_status: ", status); - if status.is_error() { + if tcp_child.is_null() { unsafe { - ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); - ((*bs).free_pool)(tcp_service_handles as *mut c_void); - ((*tls_binding).destroy_child)(tls_binding, tls_child); - ((*bs).free_pool)(tls_service_handles as *mut c_void); - } - return status; - } - - let mut connect_event = null_mut(); - let status = unsafe { - ((*bs).create_event)( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - Some(noop_event), - null_mut(), - &mut connect_event, - ) - }; - write_status("tcp4_tls_probe_connect_event_status: ", status); - if status.is_error() { - unsafe { - ((*tcp4).configure)(tcp4, null_mut()); - ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); ((*bs).free_pool)(tcp_service_handles as *mut c_void); ((*tls_binding).destroy_child)(tls_binding, tls_child); ((*bs).free_pool)(tls_service_handles as *mut c_void); } - return status; - } - - let mut connect_token = EfiTcp4ConnectionToken { - completion_token: EfiTcp4CompletionToken { - event: connect_event, - status: EFI_NOT_READY, - }, - }; - let submit_status = unsafe { ((*tcp4).connect)(tcp4, &mut connect_token) }; - write_status("tcp4_tls_probe_connect_submit_status: ", submit_status); - let connect_status = if submit_status.is_error() { - submit_status - } else { - poll_tcp4(tcp4, &connect_token.completion_token) - }; - write_status("tcp4_tls_probe_connect_completion: ", connect_status); - unsafe { - ((*bs).close_event)(connect_event); - } - if connect_status.is_error() { - unsafe { - ((*tcp4).configure)(tcp4, null_mut()); - ((*tcp_binding).destroy_child)(tcp_binding, tcp_child); - ((*bs).free_pool)(tcp_service_handles as *mut c_void); - ((*tls_binding).destroy_child)(tls_binding, tls_child); - ((*bs).free_pool)(tls_service_handles as *mut c_void); - } - return connect_status; + return EFI_UNSUPPORTED; } let tls = match open_protocol::(bs, tls_child, &EFI_TLS_PROTOCOL_GUID) { diff --git a/ostool/src/run/httpboot.rs b/ostool/src/run/httpboot.rs index b46bc12d..b724b5e9 100644 --- a/ostool/src/run/httpboot.rs +++ b/ostool/src/run/httpboot.rs @@ -235,6 +235,7 @@ async fn finish_httpboot_session( println!(" loader_url: {}", urls.loader_url); println!(" manifest_url: {}", urls.manifest_url); println!(" kernel_url: {}", urls.kernel_url); + println!("Waiting for board on power or reset..."); if config.power_cycle { client diff --git a/picture/start.jpg b/picture/start.jpg deleted file mode 100644 index 73a071ad2bbcafcea3d1b5c45b773d2a86242825..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 683866 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 =?+V%;;28#r>OdWem4+q-zW#$R*U1!`vSpT`c1 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%0DXq9WvJ(F8ZJA1IY5%Xq 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 |axYlWI}23_9KtB}r>z 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�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

suk8h= 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 P)S`|O)y@pO|MUL?MGR(v diff --git a/scripts/https_static_server.py b/scripts/https_static_server.py deleted file mode 100644 index 09be6f43..00000000 --- a/scripts/https_static_server.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import http.server -import ssl -from functools import partial - - -class Http11SimpleHTTPRequestHandler(http.server.SimpleHTTPRequestHandler): - protocol_version = "HTTP/1.1" - - -def main() -> None: - parser = argparse.ArgumentParser() - parser.add_argument("--bind", default="0.0.0.0") - parser.add_argument("--port", type=int, default=3443) - parser.add_argument("--root", required=True) - parser.add_argument("--cert", required=True) - parser.add_argument("--key", required=True) - args = parser.parse_args() - - handler = partial(Http11SimpleHTTPRequestHandler, directory=args.root) - httpd = http.server.ThreadingHTTPServer((args.bind, args.port), handler) - context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) - context.load_cert_chain(certfile=args.cert, keyfile=args.key) - httpd.socket = context.wrap_socket(httpd.socket, server_side=True) - print(f"https static server listening on https://{args.bind}:{args.port}/ root={args.root}", flush=True) - httpd.serve_forever() - - -if __name__ == "__main__": - main() From 839c9f78de1a85ebf79579b576fc85193ce897a8 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Thu, 28 May 2026 01:20:24 +0000 Subject: [PATCH 32/39] feat: wire up full HTTP boot loader pipeline with boot-jump feature gate and arch validation --- httpboot/Cargo.toml | 1 + httpboot/README.md | 9 ++++++++- httpboot/src/main.rs | 8 ++------ httpboot/src/uefi/entry.rs | 4 ++++ httpboot/src/uefi/http.rs | 28 ++++++++++++++++++++++------ 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/httpboot/Cargo.toml b/httpboot/Cargo.toml index 6ceba72c..63adf4f0 100644 --- a/httpboot/Cargo.toml +++ b/httpboot/Cargo.toml @@ -21,3 +21,4 @@ required-features = ["uefi-app"] [features] default = [] uefi-app = [] +boot-jump = ["uefi-app"] diff --git a/httpboot/README.md b/httpboot/README.md index b3da4697..a665d4b5 100644 --- a/httpboot/README.md +++ b/httpboot/README.md @@ -11,7 +11,7 @@ Current status: - When the loader is started from a local EFI system partition instead of HTTP Boot, it can use the compile-time `OSTOOL_HTTPBOOT_MANIFEST_URL` fallback. - The loader uses UEFI HTTP Protocol to download `manifest.json` and the kernel `.bin`. - The loader places the kernel at `kernel_load_addr`, prepares memory-map and `ExitBootServices` state, and prints the entry plan. -- The final boot jump is behind a default-off compile-time safety switch. +- The final boot jump is behind the default-off `boot-jump` feature. Build the x86_64 loader after installing the target: @@ -22,6 +22,13 @@ mkdir -p target/httpboot cp target/x86_64-unknown-uefi/debug/httpboot.efi target/httpboot/BOOTX64.EFI ``` +The default build downloads and loads the kernel, prints the jump plan, and stops before `ExitBootServices`. +Build with `boot-jump` only after the x86_64 AxVisor direct-entry ABI is ready: + +```bash +cargo build -p httpboot --features boot-jump --target x86_64-unknown-uefi +``` + Then set: ```toml diff --git a/httpboot/src/main.rs b/httpboot/src/main.rs index d7b31969..e4b57052 100644 --- a/httpboot/src/main.rs +++ b/httpboot/src/main.rs @@ -18,7 +18,7 @@ use uefi::abi::{EFI_SUCCESS, EFI_UNSUPPORTED, EfiHandle, EfiStatus, EfiSystemTab #[cfg(target_os = "uefi")] use uefi::console::write_console; #[cfg(target_os = "uefi")] -use uefi::http::print_http_protocol_probe; +use uefi::http::run_http_boot_loader; #[cfg(target_os = "uefi")] use uefi::loaded_image::{LoaderError, loader_url_from_loaded_image}; @@ -91,11 +91,7 @@ pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTa } } - write_console( - console, - "HTTP download backend is pending; manifest bytes parser linked\r\n", - ); - print_http_protocol_probe(console, image, system_table, manifest_url); + run_http_boot_loader(console, image, system_table, manifest_url); EFI_SUCCESS } diff --git a/httpboot/src/uefi/entry.rs b/httpboot/src/uefi/entry.rs index 90a2cd3e..93aca527 100644 --- a/httpboot/src/uefi/entry.rs +++ b/httpboot/src/uefi/entry.rs @@ -29,6 +29,10 @@ pub fn print_entry_plan(console: *mut EfiSimpleTextOutputProtocol, plan: &EntryP write_console(console, "\r\n"); } +pub fn target_matches_manifest(manifest_arch: &str) -> bool { + target_arch_name() == manifest_arch +} + #[allow(dead_code)] pub unsafe fn call_entry_point(plan: &EntryPlan<'_>) -> ! { unsafe { call_entry(plan.entry_point) } diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index 99ed8742..c3b700b5 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -11,7 +11,7 @@ use crate::uefi::abi::{ boot_services_from_system_table, }; use crate::uefi::console::{write_console, write_status, write_usize, write_utf16_nul}; -use crate::uefi::entry::{EntryPlan, call_entry_point, print_entry_plan}; +use crate::uefi::entry::{EntryPlan, call_entry_point, print_entry_plan, target_matches_manifest}; use httpboot::parse_downloaded_manifest; const UTF16_URL_BUFFER_SIZE: usize = 1024; @@ -21,16 +21,27 @@ const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; const MAX_KERNEL_DOWNLOAD_SIZE: usize = 256 * 1024 * 1024; const EFI_PAGE_SIZE: usize = 4096; const MEMORY_MAP_BUFFER_SIZE: usize = 64 * 1024; -const ENABLE_BOOT_JUMP: bool = false; +const ENABLE_BOOT_JUMP: bool = cfg!(feature = "boot-jump"); -pub fn print_http_protocol_probe( +pub fn run_http_boot_loader( console: *mut EfiSimpleTextOutputProtocol, image: EfiHandle, system_table: *mut EfiSystemTable, manifest_url: Option<&str>, ) { + write_console(console, "httpboot_loader_start\r\n"); + write_console(console, "boot_jump_feature: "); + write_console( + console, + if ENABLE_BOOT_JUMP { + "enabled\r\n" + } else { + "disabled\r\n" + }, + ); + let Some(boot_services) = boot_services_from_system_table(system_table) else { - write_console(console, "failed to access Boot Services for HTTP probe\r\n"); + write_console(console, "failed to access Boot Services for HTTP Boot\r\n"); return; }; @@ -55,7 +66,7 @@ pub fn print_http_protocol_probe( Err(_) => write_console(console, "failed to locate HTTP Protocol\r\n"), } - probe_http_child(console, boot_services, image, manifest_url); + run_http_child(console, boot_services, image, manifest_url); } fn count_protocol_handles( @@ -121,7 +132,7 @@ fn open_protocol_on_handle( Ok(interface as *mut T) } -fn probe_http_child( +fn run_http_child( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, image: EfiHandle, @@ -398,6 +409,11 @@ fn print_manifest_response( write_console(console, "manifest_arch: "); write_console(console, manifest.arch); write_console(console, "\r\n"); + if !target_matches_manifest(manifest.arch) { + write_console(console, "manifest_arch_rejected: target mismatch\r\n"); + free_response_headers(boot_services, message); + return; + } write_console(console, "manifest_kernel_url: "); write_console(console, manifest.kernel_url); write_console(console, "\r\n"); From 09cdec3a393bfdbcfee4656abc895666ae2843f0 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Thu, 28 May 2026 02:23:59 +0000 Subject: [PATCH 33/39] feat: support pre-built frontend assets via EMBED_WEB_DIR env --- ostool-server/build.rs | 16 ++++++++++++++++ ostool-server/src/config.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/ostool-server/build.rs b/ostool-server/build.rs index 01960dfb..d56d5129 100644 --- a/ostool-server/build.rs +++ b/ostool-server/build.rs @@ -26,6 +26,22 @@ fn main() { panic!("missing frontend directory: {}", webui_dir.display()); } + if let Some(existing_dist_dir) = env::var_os(EMBED_WEB_DIR_ENV) { + let existing_dist_dir = PathBuf::from(existing_dist_dir); + let index_html = existing_dist_dir.join("index.html"); + if !index_html.exists() { + panic!( + "{EMBED_WEB_DIR_ENV} is set but {} does not exist", + index_html.display() + ); + } + println!( + "cargo:rustc-env={EMBED_WEB_DIR_ENV}={}", + existing_dist_dir.display() + ); + return; + } + let out_dir = PathBuf::from(env::var_os("OUT_DIR").expect("missing OUT_DIR")); let web_work_dir = out_dir.join("web-work"); let web_dist_dir = out_dir.join("web-assets"); diff --git a/ostool-server/src/config.rs b/ostool-server/src/config.rs index 1595523d..a1025fcb 100644 --- a/ostool-server/src/config.rs +++ b/ostool-server/src/config.rs @@ -763,6 +763,32 @@ board_power_off_cmd = "shutdown" assert_eq!(profile.loader_file.as_deref(), Some("BOOTX64.EFI")); } + #[test] + fn asus_nuc15_x86_64_vmx_example_board_config_parses() { + let content = include_str!("../../docs/examples/Asus-nuc15-x86_64-vmx.board.toml"); + let board: BoardConfig = toml::from_str(content).unwrap(); + + assert_eq!(board.id, "Asus-nuc15-x86_64-vmx"); + assert_eq!(board.board_type, "Asus-nuc15-x86_64-vmx"); + assert!(board.tags.iter().any(|tag| tag == "vmx")); + assert!(matches!( + board.power_management, + PowerManagementConfig::Virtual(_) + )); + + let BootConfig::UefiHttp(profile) = board.boot else { + panic!("expected uefi_http"); + }; + assert_eq!(profile.boot_arch, Some(UefiBootArch::X86_64)); + assert_eq!(profile.strategy, UefiHttpStrategy::BareBinLoader); + assert_eq!(profile.loader_file.as_deref(), Some("BOOTX64.EFI")); + assert_eq!(profile.kernel_file.as_deref(), Some("kernel.bin")); + assert_eq!(profile.kernel_load_addr.as_deref(), Some("0x200000")); + assert_eq!(profile.entry_point.as_deref(), Some("0x200000")); + assert_eq!(profile.client_ip, Some("10.3.10.143".parse().unwrap())); + assert_eq!(profile.mac_address.as_deref(), Some("1c:69:7a:dc:f3:47")); + } + #[test] fn board_config_round_trip_supports_relay_power_management_key() { let board = BoardConfig { From 32a378e3fe7f957a44dea3354e6af1ccf025e14c Mon Sep 17 00:00:00 2001 From: Josen-B Date: Fri, 29 May 2026 06:42:10 +0000 Subject: [PATCH 34/39] feat: add HTTP range request support for chunked kernel download with retry logic --- httpboot/src/uefi/abi.rs | 7 +- httpboot/src/uefi/http.rs | 558 ++++++++++++++++++++++++-------- ostool-server/src/api/router.rs | 114 +++++-- ostool/src/run/httpboot.rs | 1 - 4 files changed, 528 insertions(+), 152 deletions(-) diff --git a/httpboot/src/uefi/abi.rs b/httpboot/src/uefi/abi.rs index 0e7dab82..1ca87458 100644 --- a/httpboot/src/uefi/abi.rs +++ b/httpboot/src/uefi/abi.rs @@ -9,7 +9,7 @@ pub type EfiAllocateType = u32; pub type EfiPhysicalAddress = u64; pub const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; -pub const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 0; +pub const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 2; pub const EFI_LOADER_DATA: EfiMemoryType = 2; #[repr(transparent)] @@ -19,6 +19,8 @@ pub struct EfiStatus(pub usize); pub const EFI_SUCCESS: EfiStatus = EfiStatus(0); pub const EFI_ERROR_BIT: usize = 1usize << (usize::BITS - 1); pub const EFI_UNSUPPORTED: EfiStatus = EfiStatus(EFI_ERROR_BIT | 3); +pub const EFI_NO_MAPPING: EfiStatus = EfiStatus(EFI_ERROR_BIT | 17); +pub const EFI_TIMEOUT: EfiStatus = EfiStatus(EFI_ERROR_BIT | 18); pub const EFI_NOT_READY: EfiStatus = EfiStatus(EFI_ERROR_BIT | 6); pub const EFI_LOADED_IMAGE_PROTOCOL_GUID: EfiGuid = EfiGuid { @@ -47,6 +49,7 @@ pub const TPL_CALLBACK: usize = 8; pub const HTTP_VERSION_11: u32 = 1; pub const HTTP_METHOD_GET: u32 = 0; pub const HTTP_STATUS_200_OK: u32 = 3; +pub const HTTP_STATUS_206_PARTIAL_CONTENT: u32 = 9; #[repr(C)] pub struct EfiGuid { @@ -129,7 +132,7 @@ pub struct EfiBootServices { pub exit_boot_services: extern "efiapi" fn(image_handle: EfiHandle, map_key: usize) -> EfiStatus, pub _get_next_monotonic_count: usize, - pub _stall: usize, + pub stall: extern "efiapi" fn(microseconds: usize) -> EfiStatus, pub _set_watchdog_timer: usize, pub _connect_controller: usize, pub _disconnect_controller: usize, diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index c3b700b5..bcc2d472 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -2,12 +2,13 @@ use core::ffi::c_void; use crate::uefi::abi::{ EFI_ALLOCATE_ADDRESS, EFI_HTTP_PROTOCOL_GUID, EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, - EFI_LOADER_DATA, EFI_LOCATE_BY_PROTOCOL, EFI_NOT_READY, EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, - EfiBootServices, EfiEvent, EfiGuid, EfiHandle, EfiHttpConfigAccessPoint, EfiHttpConfigData, - EfiHttpMessage, EfiHttpMessageData, EfiHttpProtocol, EfiHttpRequestData, EfiHttpResponseData, - EfiHttpToken, EfiHttpv4AccessPoint, EfiMemoryDescriptor, EfiPhysicalAddress, - EfiServiceBindingProtocol, EfiSimpleTextOutputProtocol, EfiStatus, EfiSystemTable, - HTTP_METHOD_GET, HTTP_STATUS_200_OK, HTTP_VERSION_11, TPL_CALLBACK, + EFI_LOADER_DATA, EFI_LOCATE_BY_PROTOCOL, EFI_NO_MAPPING, EFI_NOT_READY, EFI_TIMEOUT, + EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, EfiBootServices, EfiEvent, EfiGuid, EfiHandle, + EfiHttpConfigAccessPoint, EfiHttpConfigData, EfiHttpHeader, EfiHttpMessage, EfiHttpMessageData, + EfiHttpProtocol, EfiHttpRequestData, EfiHttpResponseData, EfiHttpToken, EfiHttpv4AccessPoint, + EfiMemoryDescriptor, EfiPhysicalAddress, EfiServiceBindingProtocol, + EfiSimpleTextOutputProtocol, EfiStatus, EfiSystemTable, HTTP_METHOD_GET, HTTP_STATUS_200_OK, + HTTP_STATUS_206_PARTIAL_CONTENT, HTTP_VERSION_11, TPL_CALLBACK, boot_services_from_system_table, }; use crate::uefi::console::{write_console, write_status, write_usize, write_utf16_nul}; @@ -15,9 +16,13 @@ use crate::uefi::entry::{EntryPlan, call_entry_point, print_entry_plan, target_m use httpboot::parse_downloaded_manifest; const UTF16_URL_BUFFER_SIZE: usize = 1024; +const HTTP_HOST_BUFFER_SIZE: usize = 256; const MANIFEST_BODY_BUFFER_SIZE: usize = 4096; -const KERNEL_RESPONSE_CHUNK_SIZE: usize = 16 * 1024; +const KERNEL_RANGE_CHUNK_SIZE: usize = 1024; const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; +const HTTP_REQUEST_RETRY_LIMIT: usize = 8; +const HTTP_REQUEST_RETRY_STALL_US: usize = 250_000; +const KERNEL_PROGRESS_STEP: usize = 256 * 1024; const MAX_KERNEL_DOWNLOAD_SIZE: usize = 256 * 1024 * 1024; const EFI_PAGE_SIZE: usize = 4096; const MEMORY_MAP_BUFFER_SIZE: usize = 64 * 1024; @@ -201,11 +206,7 @@ fn run_http_child( if !configure_status.is_error() { if let Some(manifest_url) = manifest_url { - let mut url_buffer = [0u16; UTF16_URL_BUFFER_SIZE]; - match write_utf16_nul(manifest_url, &mut url_buffer) { - Ok(url) => request_manifest(console, boot_services, image, http_protocol, url), - Err(_) => write_console(console, "http_request_skipped: URL too long\r\n"), - } + request_manifest(console, boot_services, image, http_protocol, manifest_url); } else { write_console( console, @@ -228,8 +229,29 @@ fn request_manifest( boot_services: &mut EfiBootServices, image: EfiHandle, http_protocol: *mut EfiHttpProtocol, - url: *mut u16, + manifest_url: &str, ) { + let mut url_buffer = [0u16; UTF16_URL_BUFFER_SIZE]; + let url = match write_utf16_nul(manifest_url, &mut url_buffer) { + Ok(url) => url, + Err(_) => { + write_console(console, "http_request_skipped: URL too long\r\n"); + return; + } + }; + let mut host_name = *b"Host\0"; + let mut host_value = [0u8; HTTP_HOST_BUFFER_SIZE]; + let host = match write_url_host_header_value(manifest_url, &mut host_value) { + Ok(host) => host, + Err(()) => { + write_console(console, "http_request_skipped: invalid URL host\r\n"); + return; + } + }; + write_console(console, "http_request_host: "); + write_console(console, host); + write_console(console, "\r\n"); + let mut event = core::ptr::null_mut(); let event_status = (boot_services.create_event)( EVT_NOTIFY_SIGNAL, @@ -245,6 +267,10 @@ fn request_manifest( return; } + let mut headers = [EfiHttpHeader { + field_name: host_name.as_mut_ptr(), + field_value: host_value.as_mut_ptr(), + }]; let mut request_data = EfiHttpRequestData { method: HTTP_METHOD_GET, url, @@ -253,8 +279,8 @@ fn request_manifest( data: EfiHttpMessageData { request: &mut request_data, }, - header_count: 0, - headers: core::ptr::null_mut(), + header_count: headers.len(), + headers: headers.as_mut_ptr(), body_length: 0, body: core::ptr::null_mut(), }; @@ -264,7 +290,7 @@ fn request_manifest( message: &mut message, }; - let request_status = unsafe { ((*http_protocol).request)(http_protocol, &mut token) }; + let request_status = submit_request_with_retries(boot_services, http_protocol, &mut token); write_console(console, "http_request_status: "); write_status(console, request_status); write_console(console, "\r\n"); @@ -287,6 +313,31 @@ fn request_manifest( extern "efiapi" fn noop_event_notify(_event: EfiEvent, _context: *mut c_void) {} +fn submit_request_with_retries( + boot_services: &mut EfiBootServices, + http_protocol: *mut EfiHttpProtocol, + token: &mut EfiHttpToken, +) -> EfiStatus { + let mut status = EFI_NOT_READY; + for attempt in 0..HTTP_REQUEST_RETRY_LIMIT { + token.status = EFI_NOT_READY; + status = unsafe { ((*http_protocol).request)(http_protocol, token) }; + if !is_transient_http_submit_status(status) { + return status; + } + + for _ in 0..8 { + let _ = unsafe { ((*http_protocol).poll)(http_protocol) }; + } + let _ = (boot_services.stall)(HTTP_REQUEST_RETRY_STALL_US * (attempt + 1)); + } + status +} + +fn is_transient_http_submit_status(status: EfiStatus) -> bool { + status == EFI_NO_MAPPING || status == EFI_NOT_READY || status == EFI_TIMEOUT +} + fn poll_http_token(http_protocol: *mut EfiHttpProtocol, token: &EfiHttpToken) -> EfiStatus { for _ in 0..HTTP_COMPLETION_POLL_LIMIT { let status = unsafe { core::ptr::read_volatile(&token.status) }; @@ -298,6 +349,23 @@ fn poll_http_token(http_protocol: *mut EfiHttpProtocol, token: &EfiHttpToken) -> unsafe { core::ptr::read_volatile(&token.status) } } +fn write_url_host_header_value<'a>(url: &str, output: &'a mut [u8]) -> Result<&'a str, ()> { + let scheme_end = url.find("://").ok_or(())?; + let authority = &url[scheme_end + 3..]; + let host_end = authority.find('/').unwrap_or(authority.len()); + if host_end == 0 { + return Err(()); + } + + let host = &authority[..host_end]; + if host.len() + 1 > output.len() { + return Err(()); + } + output[..host.len()].copy_from_slice(host.as_bytes()); + output[host.len()] = 0; + core::str::from_utf8(&output[..host.len()]).map_err(|_| ()) +} + fn receive_manifest_response( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, @@ -455,14 +523,55 @@ fn request_kernel_probe( entry_point: u64, arch: &str, ) { + download_kernel_to_load_addr( + console, + boot_services, + image, + http_protocol, + kernel_url, + kernel_size, + kernel_load_addr, + entry_point, + arch, + ); +} + +fn request_kernel_range( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + http_protocol: *mut EfiHttpProtocol, + kernel_url: &str, + range_start: usize, + range_end: usize, + dst: *mut u8, + expected_len: usize, + first: bool, +) -> Option { let mut url_buffer = [0u16; UTF16_URL_BUFFER_SIZE]; let url = match write_utf16_nul(kernel_url, &mut url_buffer) { Ok(url) => url, Err(_) => { write_console(console, "kernel_request_skipped: URL too long\r\n"); - return; + return None; } }; + let mut host_name = *b"Host\0"; + let mut host_value = [0u8; HTTP_HOST_BUFFER_SIZE]; + let host = match write_url_host_header_value(kernel_url, &mut host_value) { + Ok(host) => host, + Err(()) => { + write_console(console, "kernel_request_skipped: invalid URL host\r\n"); + return None; + } + }; + let mut range_name = *b"Range\0"; + let mut range_value = [0u8; 64]; + write_range_header_value(range_start, range_end, &mut range_value)?; + if first { + write_console(console, "kernel_request_host: "); + write_console(console, host); + write_console(console, "\r\n"); + } let mut event = core::ptr::null_mut(); let event_status = (boot_services.create_event)( @@ -472,13 +581,25 @@ fn request_kernel_probe( core::ptr::null_mut(), &mut event, ); - write_console(console, "kernel_request_event_status: "); - write_status(console, event_status); - write_console(console, "\r\n"); + if first { + write_console(console, "kernel_request_event_status: "); + write_status(console, event_status); + write_console(console, "\r\n"); + } if event_status.is_error() || event.is_null() { - return; + return None; } + let mut headers = [ + EfiHttpHeader { + field_name: host_name.as_mut_ptr(), + field_value: host_value.as_mut_ptr(), + }, + EfiHttpHeader { + field_name: range_name.as_mut_ptr(), + field_value: range_value.as_mut_ptr(), + }, + ]; let mut request_data = EfiHttpRequestData { method: HTTP_METHOD_GET, url, @@ -487,8 +608,8 @@ fn request_kernel_probe( data: EfiHttpMessageData { request: &mut request_data, }, - header_count: 0, - headers: core::ptr::null_mut(), + header_count: headers.len(), + headers: headers.as_mut_ptr(), body_length: 0, body: core::ptr::null_mut(), }; @@ -498,34 +619,53 @@ fn request_kernel_probe( message: &mut message, }; - let request_status = unsafe { ((*http_protocol).request)(http_protocol, &mut token) }; - write_console(console, "kernel_request_status: "); - write_status(console, request_status); - write_console(console, "\r\n"); + let request_status = submit_request_with_retries(boot_services, http_protocol, &mut token); + if first || request_status.is_error() { + write_console(console, "kernel_request_status: "); + write_status(console, request_status); + write_console(console, "\r\n"); + } if !request_status.is_error() { let completion = poll_http_token(http_protocol, &token); - write_console(console, "kernel_request_completion: "); - write_status(console, completion); - write_console(console, "\r\n"); - if !completion.is_error() { - download_kernel_to_load_addr( - console, - boot_services, - image, - http_protocol, - kernel_size, - kernel_load_addr, - entry_point, - arch, - ); + if first || completion.is_error() { + write_console(console, "kernel_request_completion: "); + write_status(console, completion); + write_console(console, "\r\n"); + } + if completion.is_error() { + let close_status = (boot_services.close_event)(event); + if first { + write_console(console, "kernel_request_close_event_status: "); + write_status(console, close_status); + write_console(console, "\r\n"); + } + return None; + } + let received = receive_kernel_range_body( + console, + boot_services, + http_protocol, + dst, + expected_len, + first, + ); + let close_status = (boot_services.close_event)(event); + if first { + write_console(console, "kernel_request_close_event_status: "); + write_status(console, close_status); + write_console(console, "\r\n"); } + return received; } let close_status = (boot_services.close_event)(event); - write_console(console, "kernel_request_close_event_status: "); - write_status(console, close_status); - write_console(console, "\r\n"); + if first { + write_console(console, "kernel_request_close_event_status: "); + write_status(console, close_status); + write_console(console, "\r\n"); + } + None } fn download_kernel_to_load_addr( @@ -533,6 +673,7 @@ fn download_kernel_to_load_addr( boot_services: &mut EfiBootServices, image: EfiHandle, http_protocol: *mut EfiHttpProtocol, + kernel_url: &str, expected_kernel_size: u64, kernel_load_addr: u64, entry_point: u64, @@ -566,36 +707,21 @@ fn download_kernel_to_load_addr( return; } - let mut downloaded = 0usize; - let mut checksum = 0u32; - let mut complete = false; - - while downloaded < expected_size { - let remaining = expected_size - downloaded; - let chunk_len = remaining.min(KERNEL_RESPONSE_CHUNK_SIZE); - let chunk = unsafe { (kernel_load_addr as *mut u8).add(downloaded) }; - let Some(received) = - receive_kernel_chunk(console, boot_services, http_protocol, chunk, chunk_len) - else { - break; - }; - - if received == 0 { - write_console(console, "kernel_download_stopped: zero length chunk\r\n"); - break; - } - - checksum = checksum_add(checksum, unsafe { - core::slice::from_raw_parts(chunk, received) - }); - downloaded += received; - if downloaded == expected_size { - complete = true; - } - } + let received = download_kernel_ranges( + console, + boot_services, + http_protocol, + kernel_url, + kernel_load_addr, + expected_size, + ); + let checksum = checksum_add(0, unsafe { + core::slice::from_raw_parts(kernel_load_addr as *const u8, received) + }); + let complete = received == expected_size; write_console(console, "kernel_downloaded_size: "); - write_usize(console, downloaded); + write_usize(console, received); write_console(console, "\r\n"); write_console(console, "kernel_expected_size: "); write_usize(console, expected_size); @@ -669,13 +795,152 @@ fn kernel_page_count( }) } -fn receive_kernel_chunk( +fn download_kernel_ranges( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + http_protocol: *mut EfiHttpProtocol, + kernel_url: &str, + kernel_load_addr: u64, + expected_size: usize, +) -> usize { + let mut downloaded = 0usize; + let mut next_progress = KERNEL_PROGRESS_STEP; + + while downloaded < expected_size { + let chunk_len = (expected_size - downloaded).min(KERNEL_RANGE_CHUNK_SIZE); + let range_start = downloaded; + let range_end = downloaded + chunk_len - 1; + let dst = unsafe { (kernel_load_addr as *mut u8).add(downloaded) }; + let first = downloaded == 0; + let Some(received) = request_kernel_range( + console, + boot_services, + http_protocol, + kernel_url, + range_start, + range_end, + dst, + chunk_len, + first, + ) else { + write_console(console, "kernel_download_stopped_at: "); + write_usize(console, downloaded); + write_console(console, "\r\n"); + break; + }; + if received == 0 { + write_console(console, "kernel_download_stopped: zero length chunk\r\n"); + break; + } + downloaded += received; + if downloaded >= next_progress || downloaded == expected_size { + write_console(console, "kernel_download_progress: "); + write_usize(console, downloaded); + write_console(console, "\r\n"); + while next_progress <= downloaded { + next_progress += KERNEL_PROGRESS_STEP; + } + } + } + + downloaded +} + +fn write_range_header_value(start: usize, end: usize, output: &mut [u8]) -> Option<()> { + let mut writer = ByteWriter::new(output); + writer.write_bytes(b"bytes=")?; + writer.write_usize(start)?; + writer.write_byte(b'-')?; + writer.write_usize(end)?; + writer.finish() +} + +struct ByteWriter<'a> { + output: &'a mut [u8], + len: usize, +} + +impl<'a> ByteWriter<'a> { + fn new(output: &'a mut [u8]) -> Self { + Self { output, len: 0 } + } + + fn write_byte(&mut self, byte: u8) -> Option<()> { + if self.len + 1 >= self.output.len() { + return None; + } + self.output[self.len] = byte; + self.len += 1; + Some(()) + } + + fn write_bytes(&mut self, bytes: &[u8]) -> Option<()> { + for byte in bytes { + self.write_byte(*byte)?; + } + Some(()) + } + + fn write_usize(&mut self, mut value: usize) -> Option<()> { + let mut digits = [0u8; 20]; + let mut len = 0usize; + if value == 0 { + return self.write_byte(b'0'); + } + while value > 0 && len < digits.len() { + digits[len] = b'0' + (value % 10) as u8; + value /= 10; + len += 1; + } + while len > 0 { + len -= 1; + self.write_byte(digits[len])?; + } + Some(()) + } + + fn finish(&mut self) -> Option<()> { + if self.len >= self.output.len() { + return None; + } + self.output[self.len] = 0; + Some(()) + } +} + +fn receive_kernel_range_body( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, http_protocol: *mut EfiHttpProtocol, - chunk: *mut u8, - chunk_len: usize, + body: *mut u8, + body_len: usize, + first: bool, ) -> Option { + let response = + receive_kernel_stream_chunk(console, boot_services, http_protocol, body, body_len, first)?; + if response.http_status != HTTP_STATUS_206_PARTIAL_CONTENT { + write_console( + console, + "kernel_download_stopped: HTTP status is not 206\r\n", + ); + return None; + } + Some(response.received) +} + +struct KernelChunkResponse { + received: usize, + http_status: u32, +} + +fn receive_kernel_stream_chunk( + console: *mut EfiSimpleTextOutputProtocol, + boot_services: &mut EfiBootServices, + http_protocol: *mut EfiHttpProtocol, + body: *mut u8, + body_len: usize, + first: bool, +) -> Option { let mut event = core::ptr::null_mut(); let event_status = (boot_services.create_event)( EVT_NOTIFY_SIGNAL, @@ -684,22 +949,26 @@ fn receive_kernel_chunk( core::ptr::null_mut(), &mut event, ); - write_console(console, "kernel_response_event_status: "); - write_status(console, event_status); - write_console(console, "\r\n"); + if first { + write_console(console, "kernel_response_event_status: "); + write_status(console, event_status); + write_console(console, "\r\n"); + } if event_status.is_error() || event.is_null() { return None; } - let mut response_data = EfiHttpResponseData { status_code: 0 }; + let mut response_data = EfiHttpResponseData { + status_code: HTTP_STATUS_200_OK, + }; let mut message = EfiHttpMessage { data: EfiHttpMessageData { response: &mut response_data, }, header_count: 0, headers: core::ptr::null_mut(), - body_length: chunk_len, - body: chunk as *mut c_void, + body_length: body_len, + body: body as *mut c_void, }; let mut token = EfiHttpToken { event, @@ -708,32 +977,57 @@ fn receive_kernel_chunk( }; let response_status = unsafe { ((*http_protocol).response)(http_protocol, &mut token) }; - write_console(console, "kernel_response_status: "); - write_status(console, response_status); - write_console(console, "\r\n"); + if first { + write_console(console, "kernel_response_status: "); + write_status(console, response_status); + write_console(console, "\r\n"); + } else if response_status.is_error() { + write_console(console, "kernel_stream_response_status: "); + write_status(console, response_status); + write_console(console, "\r\n"); + } - if !response_status.is_error() { - let completion = poll_http_token(http_protocol, &token); + if response_status.is_error() { + let close_status = (boot_services.close_event)(event); + if first { + write_console(console, "kernel_response_close_event_status: "); + write_status(console, close_status); + write_console(console, "\r\n"); + } + return None; + } + + let completion = poll_http_token(http_protocol, &token); + if first { write_console(console, "kernel_response_completion: "); write_status(console, completion); write_console(console, "\r\n"); if !completion.is_error() { print_kernel_chunk_response(console, boot_services, &response_data, &message); } + } else { + if completion.is_error() { + write_console(console, "kernel_stream_response_completion: "); + write_status(console, completion); + write_console(console, "\r\n"); + } + free_response_headers(boot_services, &message); } let close_status = (boot_services.close_event)(event); - write_console(console, "kernel_response_close_event_status: "); - write_status(console, close_status); - write_console(console, "\r\n"); - - if response_status.is_error() || token.status.is_error() { - return None; + if first { + write_console(console, "kernel_response_close_event_status: "); + write_status(console, close_status); + write_console(console, "\r\n"); } - if response_data.status_code != HTTP_STATUS_200_OK { + + if completion.is_error() { return None; } - Some(message.body_length) + Some(KernelChunkResponse { + received: message.body_length, + http_status: response_data.status_code, + }) } fn print_jump_readiness( @@ -789,6 +1083,10 @@ fn print_jump_readiness( kernel_size, }, ); + let free_status = (boot_services.free_pages)(kernel_load_addr, page_count); + write_console(console, "jump_skip_free_pages_status: "); + write_status(console, free_status); + write_console(console, "\r\n"); write_console( console, "jump_skipped: ExitBootServices and entry call pending\r\n", @@ -876,6 +1174,14 @@ fn maybe_exit_boot_services( image: EfiHandle, entry_plan: &EntryPlan<'_>, ) { + if !ENABLE_BOOT_JUMP { + write_console( + console, + "exit_boot_services_skipped: boot jump disabled\r\n", + ); + return; + } + let mut memory_map = [0u8; MEMORY_MAP_BUFFER_SIZE]; let mut probe = MemoryMapProbe::new(); let map_status = get_memory_map( @@ -884,38 +1190,28 @@ fn maybe_exit_boot_services( memory_map.as_mut_ptr() as *mut EfiMemoryDescriptor, memory_map.len(), ); + if !map_status.is_error() { + let exit_status = (boot_services.exit_boot_services)(image, probe.map_key); + if !exit_status.is_error() { + unsafe { call_entry_point(entry_plan) }; + } + write_console(console, "exit_boot_services_status: "); + write_status(console, exit_status); + write_console(console, "\r\n"); + retry_exit_boot_services(console, boot_services, image, entry_plan); + return; + } + write_console(console, "exit_memory_map_status: "); write_status(console, map_status); write_console(console, "\r\n"); write_console(console, "exit_memory_map_key: "); write_usize(console, probe.map_key); write_console(console, "\r\n"); - - if map_status.is_error() { - write_console( - console, - "exit_boot_services_skipped: memory map unavailable\r\n", - ); - return; - } - - if !ENABLE_BOOT_JUMP { - write_console( - console, - "exit_boot_services_skipped: boot jump disabled\r\n", - ); - return; - } - - let exit_status = (boot_services.exit_boot_services)(image, probe.map_key); - write_console(console, "exit_boot_services_status: "); - write_status(console, exit_status); - write_console(console, "\r\n"); - if exit_status.is_error() { - retry_exit_boot_services(console, boot_services, image, entry_plan); - } else { - unsafe { call_entry_point(entry_plan) }; - } + write_console( + console, + "exit_boot_services_skipped: memory map unavailable\r\n", + ); } fn retry_exit_boot_services( @@ -932,20 +1228,20 @@ fn retry_exit_boot_services( memory_map.as_mut_ptr() as *mut EfiMemoryDescriptor, memory_map.len(), ); - write_console(console, "exit_retry_memory_map_status: "); - write_status(console, map_status); - write_console(console, "\r\n"); if map_status.is_error() { + write_console(console, "exit_retry_memory_map_status: "); + write_status(console, map_status); + write_console(console, "\r\n"); return; } let exit_status = (boot_services.exit_boot_services)(image, probe.map_key); - write_console(console, "exit_retry_boot_services_status: "); - write_status(console, exit_status); - write_console(console, "\r\n"); if !exit_status.is_error() { unsafe { call_entry_point(entry_plan) }; } + write_console(console, "exit_retry_boot_services_status: "); + write_status(console, exit_status); + write_console(console, "\r\n"); } fn print_kernel_chunk_response( @@ -967,13 +1263,15 @@ fn print_kernel_chunk_response( write_usize(console, message.body_length); write_console(console, "\r\n"); - if response_data.status_code != HTTP_STATUS_200_OK { + if response_data.status_code == HTTP_STATUS_200_OK + || response_data.status_code == HTTP_STATUS_206_PARTIAL_CONTENT + { + write_console(console, "kernel_chunk_received\r\n"); + } else { write_console( console, - "kernel_download_stopped: HTTP status is not 200\r\n", + "kernel_download_stopped: unexpected HTTP status\r\n", ); - } else { - write_console(console, "kernel_chunk_received\r\n"); } free_response_headers(boot_services, message); diff --git a/ostool-server/src/api/router.rs b/ostool-server/src/api/router.rs index 06bd4f16..4eb27bd3 100644 --- a/ostool-server/src/api/router.rs +++ b/ostool-server/src/api/router.rs @@ -1119,27 +1119,38 @@ async fn power_off_board( async fn get_http_boot_file( Path((board_id, path)): Path<(String, String)>, State(state): State, + request: Request, ) -> Result { let relative_path = parse_relative_path(&path)?; - read_http_boot_current_file(&state, &board_id, &relative_path).await + read_http_boot_current_file(&state, &board_id, &relative_path, request.headers()).await } -async fn get_http_boot_short_loader(State(state): State) -> Result { - read_http_boot_current_file(&state, "l", "BOOTLOONGARCH64.EFI").await +async fn get_http_boot_short_loader( + State(state): State, + request: Request, +) -> Result { + read_http_boot_current_file(&state, "l", "BOOTLOONGARCH64.EFI", request.headers()).await } -async fn get_http_boot_short_manifest(State(state): State) -> Result { - read_http_boot_current_file(&state, "l", "manifest.json").await +async fn get_http_boot_short_manifest( + State(state): State, + request: Request, +) -> Result { + read_http_boot_current_file(&state, "l", "manifest.json", request.headers()).await } -async fn get_http_boot_short_kernel(State(state): State) -> Result { - read_http_boot_current_file(&state, "l", "kernel.bin").await +async fn get_http_boot_short_kernel( + State(state): State, + request: Request, +) -> Result { + read_http_boot_current_file(&state, "l", "kernel.bin", request.headers()).await } async fn read_http_boot_current_file( state: &AppState, board_id: &str, relative_path: &str, + headers: &HeaderMap, ) -> Result { let config = state.config.read().await.clone(); if !config.http_boot.enabled { @@ -1154,18 +1165,62 @@ async fn read_http_boot_current_file( _ => ApiError::from(anyhow::Error::from(err)), })?; let content_type = from_path(&disk_path).first_or_octet_stream().to_string(); - Ok(( - [( - header::CONTENT_TYPE, - HeaderValue::from_str(&content_type).map_err(|err| { - ApiError::service_unavailable(format!( - "invalid content type `{content_type}`: {err}" - )) - })?, - )], - body, - ) - .into_response()) + let content_type = HeaderValue::from_str(&content_type).map_err(|err| { + ApiError::service_unavailable(format!("invalid content type `{content_type}`: {err}")) + })?; + if let Some(range) = headers + .get(header::RANGE) + .and_then(|value| value.to_str().ok()) + { + if let Some((start, end)) = parse_single_byte_range(range, body.len()) { + let chunk = body[start..=end].to_vec(); + return Ok(( + StatusCode::PARTIAL_CONTENT, + [ + (header::CONTENT_TYPE, content_type), + ( + header::CONTENT_RANGE, + HeaderValue::from_str(&format!("bytes {start}-{end}/{}", body.len())) + .map_err(|err| { + ApiError::service_unavailable(format!( + "invalid content range header: {err}" + )) + })?, + ), + (header::ACCEPT_RANGES, HeaderValue::from_static("bytes")), + ], + chunk, + ) + .into_response()); + } + } + + Ok(([(header::CONTENT_TYPE, content_type)], body).into_response()) +} + +fn parse_single_byte_range(range: &str, len: usize) -> Option<(usize, usize)> { + let value = range.strip_prefix("bytes=")?; + if value.contains(',') { + return None; + } + let (start, end) = value.split_once('-')?; + if start.is_empty() { + return None; + } + let start = start.parse::().ok()?; + let mut end = if end.is_empty() { + len.checked_sub(1)? + } else { + end.parse::().ok()? + }; + if start >= len { + return None; + } + end = end.min(len - 1); + if start > end { + return None; + } + Some((start, end)) } async fn put_http_boot_file( @@ -3322,6 +3377,27 @@ mod tests { .unwrap(); assert_eq!(kernel_body.as_ref(), b"kernel-image"); + let range_kernel = app + .clone() + .oneshot( + Request::builder() + .uri("/boot/boards/uefi-http-01/current/kernel.bin") + .header(header::RANGE, "bytes=0-5") + .body(Body::empty()) + .unwrap(), + ) + .await + .unwrap(); + assert_eq!(range_kernel.status(), StatusCode::PARTIAL_CONTENT); + assert_eq!( + range_kernel.headers()[header::CONTENT_RANGE], + "bytes 0-5/12" + ); + let range_body = to_bytes(range_kernel.into_body(), usize::MAX) + .await + .unwrap(); + assert_eq!(range_body.as_ref(), b"kernel"); + let download_manifest = app .clone() .oneshot( diff --git a/ostool/src/run/httpboot.rs b/ostool/src/run/httpboot.rs index b724b5e9..438380e6 100644 --- a/ostool/src/run/httpboot.rs +++ b/ostool/src/run/httpboot.rs @@ -413,7 +413,6 @@ fn uefi_boot_arch_name(arch: &UefiBootArch) -> &'static str { UefiBootArch::Riscv64 => "riscv64", UefiBootArch::Other => "other", } - } fn normalize_required_string( From b5f51b6b63eca42411caedd01991e03009cca1cf Mon Sep 17 00:00:00 2001 From: Josen-B Date: Fri, 29 May 2026 09:51:48 +0000 Subject: [PATCH 35/39] feat: add COM1 serial port output to UEFI console module --- httpboot/src/uefi/console.rs | 69 ++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/httpboot/src/uefi/console.rs b/httpboot/src/uefi/console.rs index 1dd604cc..634086ff 100644 --- a/httpboot/src/uefi/console.rs +++ b/httpboot/src/uefi/console.rs @@ -1,6 +1,20 @@ use crate::uefi::abi::{EfiSimpleTextOutputProtocol, EfiStatus}; +const COM1_PORT: u16 = 0x3f8; +const UART_RBR_THR: u16 = 0; +const UART_IER: u16 = 1; +const UART_FCR: u16 = 2; +const UART_LCR: u16 = 3; +const UART_MCR: u16 = 4; +const UART_LSR: u16 = 5; +const UART_DLL: u16 = 0; +const UART_DLM: u16 = 1; +const UART_LSR_THRE: u8 = 1 << 5; +const UART_LCR_DLAB: u8 = 1 << 7; + pub fn write_console(console: *mut EfiSimpleTextOutputProtocol, message: &str) { + write_serial(message.as_bytes()); + let Some(console_ref) = (unsafe { console.as_mut() }) else { return; }; @@ -19,6 +33,61 @@ pub fn write_console(console: *mut EfiSimpleTextOutputProtocol, message: &str) { (console_ref.output_string)(console, buffer.as_ptr()); } +fn write_serial(bytes: &[u8]) { + init_com1(); + for byte in bytes { + if *byte == b'\n' { + serial_putc(b'\r'); + } + serial_putc(*byte); + } +} + +fn init_com1() { + unsafe { + outb(COM1_PORT + UART_IER, 0x00); + outb(COM1_PORT + UART_LCR, UART_LCR_DLAB); + outb(COM1_PORT + UART_DLL, 0x01); + outb(COM1_PORT + UART_DLM, 0x00); + outb(COM1_PORT + UART_LCR, 0x03); + outb(COM1_PORT + UART_FCR, 0xc7); + outb(COM1_PORT + UART_MCR, 0x0b); + } +} + +fn serial_putc(byte: u8) { + for _ in 0..100_000 { + if unsafe { inb(COM1_PORT + UART_LSR) } & UART_LSR_THRE != 0 { + unsafe { outb(COM1_PORT + UART_RBR_THR, byte) }; + return; + } + } +} + +unsafe fn outb(port: u16, value: u8) { + unsafe { + core::arch::asm!( + "out dx, al", + in("dx") port, + in("al") value, + options(nomem, nostack, preserves_flags) + ); + } +} + +unsafe fn inb(port: u16) -> u8 { + let value: u8; + unsafe { + core::arch::asm!( + "in al, dx", + in("dx") port, + out("al") value, + options(nomem, nostack, preserves_flags) + ); + } + value +} + pub fn write_usize(console: *mut EfiSimpleTextOutputProtocol, mut value: usize) { let mut digits = [0u8; 20]; let mut len = 0; From 2171eb4f03bb97e50f23dfea47d85e3f78945082 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 1 Jun 2026 01:33:00 +0000 Subject: [PATCH 36/39] feat: pass boot info with conventional memory regions to kernel entry point --- httpboot/src/uefi/abi.rs | 1 + httpboot/src/uefi/console.rs | 15 ++++++ httpboot/src/uefi/entry.rs | 38 +++++++++------ httpboot/src/uefi/http.rs | 92 ++++++++++++++++++++++++++++++++---- 4 files changed, 124 insertions(+), 22 deletions(-) diff --git a/httpboot/src/uefi/abi.rs b/httpboot/src/uefi/abi.rs index 1ca87458..46a2daa4 100644 --- a/httpboot/src/uefi/abi.rs +++ b/httpboot/src/uefi/abi.rs @@ -11,6 +11,7 @@ pub type EfiPhysicalAddress = u64; pub const EFI_LOCATE_BY_PROTOCOL: EfiLocateSearchType = 2; pub const EFI_ALLOCATE_ADDRESS: EfiAllocateType = 2; pub const EFI_LOADER_DATA: EfiMemoryType = 2; +pub const EFI_CONVENTIONAL_MEMORY: EfiMemoryType = 7; #[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq)] diff --git a/httpboot/src/uefi/console.rs b/httpboot/src/uefi/console.rs index 634086ff..64bead58 100644 --- a/httpboot/src/uefi/console.rs +++ b/httpboot/src/uefi/console.rs @@ -1,4 +1,5 @@ use crate::uefi::abi::{EfiSimpleTextOutputProtocol, EfiStatus}; +use core::sync::atomic::{AtomicBool, Ordering}; const COM1_PORT: u16 = 0x3f8; const UART_RBR_THR: u16 = 0; @@ -10,7 +11,9 @@ const UART_LSR: u16 = 5; const UART_DLL: u16 = 0; const UART_DLM: u16 = 1; const UART_LSR_THRE: u8 = 1 << 5; +const UART_LSR_TEMT: u8 = 1 << 6; const UART_LCR_DLAB: u8 = 1 << 7; +static COM1_INITIALIZED: AtomicBool = AtomicBool::new(false); pub fn write_console(console: *mut EfiSimpleTextOutputProtocol, message: &str) { write_serial(message.as_bytes()); @@ -44,6 +47,9 @@ fn write_serial(bytes: &[u8]) { } fn init_com1() { + if COM1_INITIALIZED.swap(true, Ordering::AcqRel) { + return; + } unsafe { outb(COM1_PORT + UART_IER, 0x00); outb(COM1_PORT + UART_LCR, UART_LCR_DLAB); @@ -59,6 +65,15 @@ fn serial_putc(byte: u8) { for _ in 0..100_000 { if unsafe { inb(COM1_PORT + UART_LSR) } & UART_LSR_THRE != 0 { unsafe { outb(COM1_PORT + UART_RBR_THR, byte) }; + wait_serial_empty(); + return; + } + } +} + +fn wait_serial_empty() { + for _ in 0..100_000 { + if unsafe { inb(COM1_PORT + UART_LSR) } & UART_LSR_TEMT != 0 { return; } } diff --git a/httpboot/src/uefi/entry.rs b/httpboot/src/uefi/entry.rs index 93aca527..e77fff47 100644 --- a/httpboot/src/uefi/entry.rs +++ b/httpboot/src/uefi/entry.rs @@ -1,11 +1,13 @@ use crate::uefi::abi::EfiSimpleTextOutputProtocol; use crate::uefi::console::{write_console, write_usize}; +#[derive(Clone, Copy)] pub struct EntryPlan<'a> { pub arch: &'a str, pub load_addr: u64, pub entry_point: u64, pub kernel_size: usize, + pub boot_info: usize, } pub fn print_entry_plan(console: *mut EfiSimpleTextOutputProtocol, plan: &EntryPlan<'_>) { @@ -27,6 +29,9 @@ pub fn print_entry_plan(console: *mut EfiSimpleTextOutputProtocol, plan: &EntryP write_console(console, "entry_call_kernel_size: "); write_usize(console, plan.kernel_size); write_console(console, "\r\n"); + write_console(console, "entry_call_boot_info: 0x"); + write_hex_usize(console, plan.boot_info); + write_console(console, "\r\n"); } pub fn target_matches_manifest(manifest_arch: &str) -> bool { @@ -35,26 +40,27 @@ pub fn target_matches_manifest(manifest_arch: &str) -> bool { #[allow(dead_code)] pub unsafe fn call_entry_point(plan: &EntryPlan<'_>) -> ! { - unsafe { call_entry(plan.entry_point) } + unsafe { call_entry(plan.entry_point, plan.boot_info) } } #[cfg(target_arch = "x86_64")] #[allow(dead_code)] -unsafe fn call_entry(entry_point: u64) -> ! { - let entry: extern "sysv64" fn() -> ! = unsafe { core::mem::transmute(entry_point as usize) }; - entry() +unsafe fn call_entry(entry_point: u64, boot_info: usize) -> ! { + let entry: extern "sysv64" fn(usize) -> ! = + unsafe { core::mem::transmute(entry_point as usize) }; + entry(boot_info) } #[cfg(target_arch = "aarch64")] -unsafe fn call_entry(entry_point: u64) -> ! { - let entry: extern "C" fn() -> ! = unsafe { core::mem::transmute(entry_point as usize) }; - entry() +unsafe fn call_entry(entry_point: u64, boot_info: usize) -> ! { + let entry: extern "C" fn(usize) -> ! = unsafe { core::mem::transmute(entry_point as usize) }; + entry(boot_info) } #[cfg(target_arch = "riscv64")] -unsafe fn call_entry(entry_point: u64) -> ! { - let entry: extern "C" fn() -> ! = unsafe { core::mem::transmute(entry_point as usize) }; - entry() +unsafe fn call_entry(entry_point: u64, boot_info: usize) -> ! { + let entry: extern "C" fn(usize) -> ! = unsafe { core::mem::transmute(entry_point as usize) }; + entry(boot_info) } #[cfg(not(any( @@ -62,7 +68,7 @@ unsafe fn call_entry(entry_point: u64) -> ! { target_arch = "aarch64", target_arch = "riscv64" )))] -unsafe fn call_entry(_entry_point: u64) -> ! { +unsafe fn call_entry(_entry_point: u64, _boot_info: usize) -> ! { loop { core::hint::spin_loop(); } @@ -70,9 +76,9 @@ unsafe fn call_entry(_entry_point: u64) -> ! { fn calling_convention_note(manifest_arch: &str) -> &'static str { match (target_arch_name(), manifest_arch) { - ("x86_64", "x86_64") => "x86_64 extern sysv64 no-arg entry", - ("aarch64", "aarch64") => "aarch64 extern C no-arg entry", - ("riscv64", "riscv64") => "riscv64 extern C no-arg entry", + ("x86_64", "x86_64") => "x86_64 extern sysv64 boot-info entry", + ("aarch64", "aarch64") => "aarch64 extern C boot-info entry", + ("riscv64", "riscv64") => "riscv64 extern C boot-info entry", _ => "target/manifest arch mismatch or unvalidated entry ABI", } } @@ -114,3 +120,7 @@ fn write_hex_u64(console: *mut EfiSimpleTextOutputProtocol, value: u64) { let text = core::str::from_utf8(&output).unwrap_or("????????????????"); write_console(console, text); } + +fn write_hex_usize(console: *mut EfiSimpleTextOutputProtocol, value: usize) { + write_hex_u64(console, value as u64); +} diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index bcc2d472..24c37ced 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -2,11 +2,12 @@ use core::ffi::c_void; use crate::uefi::abi::{ EFI_ALLOCATE_ADDRESS, EFI_HTTP_PROTOCOL_GUID, EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, - EFI_LOADER_DATA, EFI_LOCATE_BY_PROTOCOL, EFI_NO_MAPPING, EFI_NOT_READY, EFI_TIMEOUT, - EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, EfiBootServices, EfiEvent, EfiGuid, EfiHandle, - EfiHttpConfigAccessPoint, EfiHttpConfigData, EfiHttpHeader, EfiHttpMessage, EfiHttpMessageData, - EfiHttpProtocol, EfiHttpRequestData, EfiHttpResponseData, EfiHttpToken, EfiHttpv4AccessPoint, - EfiMemoryDescriptor, EfiPhysicalAddress, EfiServiceBindingProtocol, + EFI_CONVENTIONAL_MEMORY, EFI_LOADER_DATA, EFI_LOCATE_BY_PROTOCOL, EFI_NO_MAPPING, + EFI_NOT_READY, EFI_TIMEOUT, EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, EfiBootServices, EfiEvent, + EfiGuid, EfiHandle, EfiHttpConfigAccessPoint, EfiHttpConfigData, EfiHttpHeader, + EfiHttpMessage, EfiHttpMessageData, EfiHttpProtocol, EfiHttpRequestData, EfiHttpResponseData, + EfiHttpToken, EfiHttpv4AccessPoint, EfiMemoryDescriptor, EfiPhysicalAddress, + EfiServiceBindingProtocol, EfiSimpleTextOutputProtocol, EfiStatus, EfiSystemTable, HTTP_METHOD_GET, HTTP_STATUS_200_OK, HTTP_STATUS_206_PARTIAL_CONTENT, HTTP_VERSION_11, TPL_CALLBACK, boot_services_from_system_table, @@ -26,8 +27,37 @@ const KERNEL_PROGRESS_STEP: usize = 256 * 1024; const MAX_KERNEL_DOWNLOAD_SIZE: usize = 256 * 1024 * 1024; const EFI_PAGE_SIZE: usize = 4096; const MEMORY_MAP_BUFFER_SIZE: usize = 64 * 1024; +const OSTOOL_BOOT_INFO_MAGIC: u64 = 0x4f53_544f_4f4c_4249; +const OSTOOL_BOOT_INFO_VERSION: u32 = 1; +const OSTOOL_BOOT_INFO_MAX_RAM_REGIONS: usize = 32; const ENABLE_BOOT_JUMP: bool = cfg!(feature = "boot-jump"); +#[repr(C)] +#[derive(Clone, Copy)] +struct OstoolRamRegion { + start: u64, + size: u64, +} + +#[repr(C)] +struct OstoolBootInfo { + magic: u64, + version: u32, + region_count: u32, + regions: [OstoolRamRegion; OSTOOL_BOOT_INFO_MAX_RAM_REGIONS], +} + +impl OstoolBootInfo { + fn new() -> Self { + Self { + magic: OSTOOL_BOOT_INFO_MAGIC, + version: OSTOOL_BOOT_INFO_VERSION, + region_count: 0, + regions: [OstoolRamRegion { start: 0, size: 0 }; OSTOOL_BOOT_INFO_MAX_RAM_REGIONS], + } + } +} + pub fn run_http_boot_loader( console: *mut EfiSimpleTextOutputProtocol, image: EfiHandle, @@ -1059,6 +1089,7 @@ fn print_jump_readiness( load_addr: kernel_load_addr, entry_point, kernel_size, + boot_info: 0, }, ); write_console(console, "boot_jump_enabled: "); @@ -1081,6 +1112,7 @@ fn print_jump_readiness( load_addr: kernel_load_addr, entry_point, kernel_size, + boot_info: 0, }, ); let free_status = (boot_services.free_pages)(kernel_load_addr, page_count); @@ -1191,14 +1223,20 @@ fn maybe_exit_boot_services( memory_map.len(), ); if !map_status.is_error() { + let mut boot_info = OstoolBootInfo::new(); + populate_boot_info_from_memory_map(&mut boot_info, &memory_map, &probe); + let entry_plan = EntryPlan { + boot_info: core::ptr::addr_of!(boot_info) as usize, + ..*entry_plan + }; let exit_status = (boot_services.exit_boot_services)(image, probe.map_key); if !exit_status.is_error() { - unsafe { call_entry_point(entry_plan) }; + unsafe { call_entry_point(&entry_plan) }; } write_console(console, "exit_boot_services_status: "); write_status(console, exit_status); write_console(console, "\r\n"); - retry_exit_boot_services(console, boot_services, image, entry_plan); + retry_exit_boot_services(console, boot_services, image, &entry_plan); return; } @@ -1235,15 +1273,53 @@ fn retry_exit_boot_services( return; } + let mut boot_info = OstoolBootInfo::new(); + populate_boot_info_from_memory_map(&mut boot_info, &memory_map, &probe); + let entry_plan = EntryPlan { + boot_info: core::ptr::addr_of!(boot_info) as usize, + ..*entry_plan + }; let exit_status = (boot_services.exit_boot_services)(image, probe.map_key); if !exit_status.is_error() { - unsafe { call_entry_point(entry_plan) }; + unsafe { call_entry_point(&entry_plan) }; } write_console(console, "exit_retry_boot_services_status: "); write_status(console, exit_status); write_console(console, "\r\n"); } +fn populate_boot_info_from_memory_map( + boot_info: &mut OstoolBootInfo, + memory_map: &[u8], + probe: &MemoryMapProbe, +) { + if probe.descriptor_size < core::mem::size_of::() { + return; + } + + let mut offset = 0usize; + while offset + core::mem::size_of::() <= probe.memory_map_size + && offset + core::mem::size_of::() <= memory_map.len() + { + let descriptor = unsafe { + core::ptr::read_unaligned( + memory_map.as_ptr().add(offset) as *const EfiMemoryDescriptor + ) + }; + if descriptor.memory_type == EFI_CONVENTIONAL_MEMORY + && boot_info.region_count < OSTOOL_BOOT_INFO_MAX_RAM_REGIONS as u32 + { + let index = boot_info.region_count as usize; + boot_info.regions[index] = OstoolRamRegion { + start: descriptor.physical_start, + size: descriptor.number_of_pages.saturating_mul(EFI_PAGE_SIZE as u64), + }; + boot_info.region_count += 1; + } + offset += probe.descriptor_size; + } +} + fn print_kernel_chunk_response( console: *mut EfiSimpleTextOutputProtocol, boot_services: &mut EfiBootServices, From 5411e8e63f259093c4a0e0f0e74e00dd1c860005 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 1 Jun 2026 05:09:36 +0000 Subject: [PATCH 37/39] refactor: streamline UEFI HTTP boot console output and add retry loop --- httpboot/src/main.rs | 63 ++-- httpboot/src/uefi/console.rs | 34 +- httpboot/src/uefi/entry.rs | 35 +- httpboot/src/uefi/http.rs | 649 +++++++++++------------------------ 4 files changed, 226 insertions(+), 555 deletions(-) diff --git a/httpboot/src/main.rs b/httpboot/src/main.rs index e4b57052..b7785416 100644 --- a/httpboot/src/main.rs +++ b/httpboot/src/main.rs @@ -14,7 +14,7 @@ use httpboot::write_sibling_manifest_url; mod uefi; #[cfg(target_os = "uefi")] -use uefi::abi::{EFI_SUCCESS, EFI_UNSUPPORTED, EfiHandle, EfiStatus, EfiSystemTable}; +use uefi::abi::{EFI_UNSUPPORTED, EfiHandle, EfiStatus, EfiSystemTable}; #[cfg(target_os = "uefi")] use uefi::console::write_console; #[cfg(target_os = "uefi")] @@ -40,60 +40,53 @@ pub extern "efiapi" fn efi_main(image: EfiHandle, system_table: *mut EfiSystemTa }; write_console(console, "ostool HTTP Boot\r\n"); - write_console(console, "manifest parser core linked\r\n"); let mut device_path_buffer = [0u8; DEVICE_PATH_BUFFER_SIZE]; let mut manifest_url_buffer = [0u8; URL_BUFFER_SIZE]; let mut manifest_url = None; - match loader_url_from_loaded_image(image, system_table, &mut device_path_buffer) { - Ok(loader_url) => { - write_console(console, "loader_url: "); - write_console(console, loader_url); - write_console(console, "\r\n"); - - match write_sibling_manifest_url(loader_url, &mut manifest_url_buffer) { - Ok(manifest_url_text) => { - write_console(console, "manifest_url: "); - write_console(console, manifest_url_text); - write_console(console, "\r\n"); - manifest_url = Some(manifest_url_text); + let loaded_image_error = + match loader_url_from_loaded_image(image, system_table, &mut device_path_buffer) { + Ok(loader_url) => { + match write_sibling_manifest_url(loader_url, &mut manifest_url_buffer) { + Ok(manifest_url_text) => { + manifest_url = Some(manifest_url_text); + None + } + Err(_) => Some("failed to build manifest URL"), } - Err(_) => write_console(console, "failed to build manifest URL\r\n"), } - } - Err(LoaderError::ProtocolUnavailable) => { - write_console(console, "failed to open Loaded Image Protocol\r\n") - } - Err(LoaderError::MissingFilePath) => { - write_console(console, "loaded image has no file path\r\n") - } - Err(LoaderError::DevicePathTooLarge) => { - write_console(console, "loaded image device path is too large\r\n") - } - Err(LoaderError::InvalidDevicePath) => { - write_console(console, "loaded image device path has no URI\r\n") - } - } + Err(LoaderError::ProtocolUnavailable) => Some("failed to open Loaded Image Protocol"), + Err(LoaderError::MissingFilePath) => Some("loaded image has no file path"), + Err(LoaderError::DevicePathTooLarge) => Some("loaded image device path is too large"), + Err(LoaderError::InvalidDevicePath) => Some("loaded image device path has no URI"), + }; if manifest_url.is_none() { match embedded_manifest_url() { Some(url) => { - write_console(console, "embedded_manifest_url: "); - write_console(console, url); - write_console(console, "\r\n"); manifest_url = Some(url); } None => { - write_console(console, "embedded_manifest_url_unset: "); + write_console(console, "manifest: unavailable\r\n"); + if let Some(error) = loaded_image_error { + write_console(console, "reason: "); + write_console(console, error); + write_console(console, "\r\n"); + } + write_console(console, "hint: set "); write_console(console, EMBEDDED_MANIFEST_URL_ENV); write_console(console, "\r\n"); } } } - run_http_boot_loader(console, image, system_table, manifest_url); + if let Some(url) = manifest_url { + write_console(console, "manifest: "); + write_console(console, url); + write_console(console, "\r\n"); + } - EFI_SUCCESS + run_http_boot_loader(console, image, system_table, manifest_url) } #[cfg(target_os = "uefi")] diff --git a/httpboot/src/uefi/console.rs b/httpboot/src/uefi/console.rs index 64bead58..814e4f95 100644 --- a/httpboot/src/uefi/console.rs +++ b/httpboot/src/uefi/console.rs @@ -1,4 +1,4 @@ -use crate::uefi::abi::{EfiSimpleTextOutputProtocol, EfiStatus}; +use crate::uefi::abi::EfiSimpleTextOutputProtocol; use core::sync::atomic::{AtomicBool, Ordering}; const COM1_PORT: u16 = 0x3f8; @@ -126,11 +126,6 @@ pub fn write_usize(console: *mut EfiSimpleTextOutputProtocol, mut value: usize) write_console(console, text); } -pub fn write_status(console: *mut EfiSimpleTextOutputProtocol, status: EfiStatus) { - write_console(console, "0x"); - write_hex_usize(console, status.0); -} - pub fn write_utf16_nul<'a>(input: &str, output: &'a mut [u16]) -> Result<*mut u16, ()> { let mut index = 0; for unit in input.encode_utf16() { @@ -143,30 +138,3 @@ pub fn write_utf16_nul<'a>(input: &str, output: &'a mut [u16]) -> Result<*mut u1 output[index] = 0; Ok(output.as_mut_ptr()) } - -fn write_hex_usize(console: *mut EfiSimpleTextOutputProtocol, mut value: usize) { - let mut digits = [0u8; 16]; - let mut len = 0; - - if value == 0 { - write_console(console, "0"); - return; - } - - while value > 0 && len < digits.len() { - let digit = (value & 0xf) as u8; - digits[len] = match digit { - 0..=9 => b'0' + digit, - _ => b'a' + (digit - 10), - }; - value >>= 4; - len += 1; - } - - let mut output = [0u8; 16]; - for index in 0..len { - output[index] = digits[len - index - 1]; - } - let text = core::str::from_utf8(&output[..len]).unwrap_or("?"); - write_console(console, text); -} diff --git a/httpboot/src/uefi/entry.rs b/httpboot/src/uefi/entry.rs index e77fff47..e31694ae 100644 --- a/httpboot/src/uefi/entry.rs +++ b/httpboot/src/uefi/entry.rs @@ -11,26 +11,14 @@ pub struct EntryPlan<'a> { } pub fn print_entry_plan(console: *mut EfiSimpleTextOutputProtocol, plan: &EntryPlan<'_>) { - write_console(console, "entry_call_arch: "); - write_console(console, plan.arch); - write_console(console, "\r\n"); - write_console(console, "entry_call_target_arch: "); - write_console(console, target_arch_name()); - write_console(console, "\r\n"); - write_console(console, "entry_call_convention: "); - write_console(console, calling_convention_note(plan.arch)); - write_console(console, "\r\n"); - write_console(console, "entry_call_load_addr: 0x"); + write_console(console, "jump: load=0x"); write_hex_u64(console, plan.load_addr); - write_console(console, "\r\n"); - write_console(console, "entry_call_entry_point: 0x"); + write_console(console, " entry=0x"); write_hex_u64(console, plan.entry_point); - write_console(console, "\r\n"); - write_console(console, "entry_call_kernel_size: "); + write_console(console, " size="); write_usize(console, plan.kernel_size); - write_console(console, "\r\n"); - write_console(console, "entry_call_boot_info: 0x"); - write_hex_usize(console, plan.boot_info); + write_console(console, " arch="); + write_console(console, plan.arch); write_console(console, "\r\n"); } @@ -74,15 +62,6 @@ unsafe fn call_entry(_entry_point: u64, _boot_info: usize) -> ! { } } -fn calling_convention_note(manifest_arch: &str) -> &'static str { - match (target_arch_name(), manifest_arch) { - ("x86_64", "x86_64") => "x86_64 extern sysv64 boot-info entry", - ("aarch64", "aarch64") => "aarch64 extern C boot-info entry", - ("riscv64", "riscv64") => "riscv64 extern C boot-info entry", - _ => "target/manifest arch mismatch or unvalidated entry ABI", - } -} - fn target_arch_name() -> &'static str { #[cfg(target_arch = "x86_64")] { @@ -120,7 +99,3 @@ fn write_hex_u64(console: *mut EfiSimpleTextOutputProtocol, value: u64) { let text = core::str::from_utf8(&output).unwrap_or("????????????????"); write_console(console, text); } - -fn write_hex_usize(console: *mut EfiSimpleTextOutputProtocol, value: usize) { - write_hex_u64(console, value as u64); -} diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index 24c37ced..347566b8 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -1,18 +1,17 @@ use core::ffi::c_void; use crate::uefi::abi::{ - EFI_ALLOCATE_ADDRESS, EFI_HTTP_PROTOCOL_GUID, EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, - EFI_CONVENTIONAL_MEMORY, EFI_LOADER_DATA, EFI_LOCATE_BY_PROTOCOL, EFI_NO_MAPPING, - EFI_NOT_READY, EFI_TIMEOUT, EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, EfiBootServices, EfiEvent, - EfiGuid, EfiHandle, EfiHttpConfigAccessPoint, EfiHttpConfigData, EfiHttpHeader, - EfiHttpMessage, EfiHttpMessageData, EfiHttpProtocol, EfiHttpRequestData, EfiHttpResponseData, - EfiHttpToken, EfiHttpv4AccessPoint, EfiMemoryDescriptor, EfiPhysicalAddress, - EfiServiceBindingProtocol, - EfiSimpleTextOutputProtocol, EfiStatus, EfiSystemTable, HTTP_METHOD_GET, HTTP_STATUS_200_OK, - HTTP_STATUS_206_PARTIAL_CONTENT, HTTP_VERSION_11, TPL_CALLBACK, - boot_services_from_system_table, + EFI_ALLOCATE_ADDRESS, EFI_CONVENTIONAL_MEMORY, EFI_HTTP_PROTOCOL_GUID, + EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, EFI_LOADER_DATA, EFI_LOCATE_BY_PROTOCOL, + EFI_NO_MAPPING, EFI_NOT_READY, EFI_SUCCESS, EFI_TIMEOUT, EFI_UNSUPPORTED, EVT_NOTIFY_SIGNAL, + EfiBootServices, EfiEvent, EfiGuid, EfiHandle, EfiHttpConfigAccessPoint, EfiHttpConfigData, + EfiHttpHeader, EfiHttpMessage, EfiHttpMessageData, EfiHttpProtocol, EfiHttpRequestData, + EfiHttpResponseData, EfiHttpToken, EfiHttpv4AccessPoint, EfiMemoryDescriptor, + EfiPhysicalAddress, EfiServiceBindingProtocol, EfiSimpleTextOutputProtocol, EfiStatus, + EfiSystemTable, HTTP_METHOD_GET, HTTP_STATUS_200_OK, HTTP_STATUS_206_PARTIAL_CONTENT, + HTTP_VERSION_11, TPL_CALLBACK, boot_services_from_system_table, }; -use crate::uefi::console::{write_console, write_status, write_usize, write_utf16_nul}; +use crate::uefi::console::{write_console, write_usize, write_utf16_nul}; use crate::uefi::entry::{EntryPlan, call_entry_point, print_entry_plan, target_matches_manifest}; use httpboot::parse_downloaded_manifest; @@ -23,7 +22,9 @@ const KERNEL_RANGE_CHUNK_SIZE: usize = 1024; const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; const HTTP_REQUEST_RETRY_LIMIT: usize = 8; const HTTP_REQUEST_RETRY_STALL_US: usize = 250_000; -const KERNEL_PROGRESS_STEP: usize = 256 * 1024; +const HTTP_BOOT_ROUND_RETRY_STALL_US: usize = 3_000_000; +const KERNEL_PROGRESS_STEP_PERCENT: usize = 5; +const KERNEL_PROGRESS_BAR_WIDTH: usize = 80; const MAX_KERNEL_DOWNLOAD_SIZE: usize = 256 * 1024 * 1024; const EFI_PAGE_SIZE: usize = 4096; const MEMORY_MAP_BUFFER_SIZE: usize = 64 * 1024; @@ -63,67 +64,18 @@ pub fn run_http_boot_loader( image: EfiHandle, system_table: *mut EfiSystemTable, manifest_url: Option<&str>, -) { - write_console(console, "httpboot_loader_start\r\n"); - write_console(console, "boot_jump_feature: "); - write_console( - console, - if ENABLE_BOOT_JUMP { - "enabled\r\n" - } else { - "disabled\r\n" - }, - ); - +) -> EfiStatus { let Some(boot_services) = boot_services_from_system_table(system_table) else { - write_console(console, "failed to access Boot Services for HTTP Boot\r\n"); - return; + write_console(console, "error: Boot Services unavailable\r\n"); + return EFI_SUCCESS; }; - match count_protocol_handles(boot_services, &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID) { - Ok(count) => { - write_console(console, "http_service_binding_handles: "); - write_usize(console, count); - write_console(console, "\r\n"); - } - Err(_) => write_console( - console, - "failed to locate HTTP Service Binding Protocol\r\n", - ), + let mut round = 0usize; + loop { + round += 1; + run_http_child(console, boot_services, image, manifest_url, round > 3); + let _ = (boot_services.stall)(HTTP_BOOT_ROUND_RETRY_STALL_US); } - - match count_protocol_handles(boot_services, &EFI_HTTP_PROTOCOL_GUID) { - Ok(count) => { - write_console(console, "http_protocol_handles: "); - write_usize(console, count); - write_console(console, "\r\n"); - } - Err(_) => write_console(console, "failed to locate HTTP Protocol\r\n"), - } - - run_http_child(console, boot_services, image, manifest_url); -} - -fn count_protocol_handles( - boot_services: &mut EfiBootServices, - protocol: &EfiGuid, -) -> Result { - let mut handle_count = 0usize; - let mut handles = core::ptr::null_mut(); - let status = (boot_services.locate_handle_buffer)( - EFI_LOCATE_BY_PROTOCOL, - protocol, - core::ptr::null_mut(), - &mut handle_count, - &mut handles, - ); - if status.is_error() { - return Err(status); - } - if !handles.is_null() { - let _ = (boot_services.free_pool)(handles as *mut c_void); - } - Ok(handle_count) } fn first_protocol_handle( @@ -172,17 +124,15 @@ fn run_http_child( boot_services: &mut EfiBootServices, image: EfiHandle, manifest_url: Option<&str>, + show_errors: bool, ) { let service_handle = match first_protocol_handle(boot_services, &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID) { Ok(handle) => handle, - Err(status) => { - write_console( - console, - "http_create_child_skipped: service binding not found ", - ); - write_status(console, status); - write_console(console, "\r\n"); + Err(_) => { + if show_errors { + write_console(console, "error: HTTP service binding unavailable\r\n"); + } return; } }; @@ -193,10 +143,10 @@ fn run_http_child( &EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, ) { Ok(service_binding) => service_binding, - Err(status) => { - write_console(console, "http_service_binding_open_failed: "); - write_status(console, status); - write_console(console, "\r\n"); + Err(_) => { + if show_errors { + write_console(console, "error: failed to open HTTP service binding\r\n"); + } return; } }; @@ -204,10 +154,10 @@ fn run_http_child( let mut child_handle = core::ptr::null_mut(); let create_status = unsafe { ((*service_binding).create_child)(service_binding, &mut child_handle) }; - write_console(console, "http_create_child_status: "); - write_status(console, create_status); - write_console(console, "\r\n"); if create_status.is_error() || child_handle.is_null() { + if show_errors { + write_console(console, "error: failed to create HTTP child\r\n"); + } return; } @@ -216,39 +166,37 @@ fn run_http_child( child_handle, &EFI_HTTP_PROTOCOL_GUID, ) { - Ok(http_protocol) => { - write_console(console, "http_child_protocol_status: 0x0\r\n"); - http_protocol - } - Err(status) => { - write_console(console, "http_child_protocol_status: "); - write_status(console, status); - write_console(console, "\r\n"); + Ok(http_protocol) => http_protocol, + Err(_) => { + if show_errors { + write_console(console, "error: failed to open HTTP protocol\r\n"); + } destroy_http_child(console, service_binding, child_handle); return; } }; let configure_status = configure_http_ipv4_default(http_protocol); - write_console(console, "http_configure_status: "); - write_status(console, configure_status); - write_console(console, "\r\n"); if !configure_status.is_error() { if let Some(manifest_url) = manifest_url { - request_manifest(console, boot_services, image, http_protocol, manifest_url); - } else { - write_console( + request_manifest( console, - "http_request_skipped: manifest URL unavailable\r\n", + boot_services, + image, + http_protocol, + manifest_url, + show_errors, ); + } else { + write_console(console, "error: manifest URL unavailable\r\n"); } - let reset_status = - unsafe { ((*http_protocol).configure)(http_protocol, core::ptr::null_mut()) }; - write_console(console, "http_reset_status: "); - write_status(console, reset_status); - write_console(console, "\r\n"); + let _ = unsafe { ((*http_protocol).configure)(http_protocol, core::ptr::null_mut()) }; + } else { + if show_errors { + write_console(console, "error: failed to configure HTTP IPv4\r\n"); + } } destroy_http_child(console, service_binding, child_handle); @@ -260,27 +208,29 @@ fn request_manifest( image: EfiHandle, http_protocol: *mut EfiHttpProtocol, manifest_url: &str, + show_errors: bool, ) { let mut url_buffer = [0u16; UTF16_URL_BUFFER_SIZE]; let url = match write_utf16_nul(manifest_url, &mut url_buffer) { Ok(url) => url, Err(_) => { - write_console(console, "http_request_skipped: URL too long\r\n"); + if show_errors { + write_console(console, "error: manifest URL too long\r\n"); + } return; } }; let mut host_name = *b"Host\0"; let mut host_value = [0u8; HTTP_HOST_BUFFER_SIZE]; - let host = match write_url_host_header_value(manifest_url, &mut host_value) { - Ok(host) => host, + match write_url_host_header_value(manifest_url, &mut host_value) { + Ok(_) => {} Err(()) => { - write_console(console, "http_request_skipped: invalid URL host\r\n"); + if show_errors { + write_console(console, "error: invalid manifest URL host\r\n"); + } return; } }; - write_console(console, "http_request_host: "); - write_console(console, host); - write_console(console, "\r\n"); let mut event = core::ptr::null_mut(); let event_status = (boot_services.create_event)( @@ -290,10 +240,13 @@ fn request_manifest( core::ptr::null_mut(), &mut event, ); - write_console(console, "http_request_event_status: "); - write_status(console, event_status); - write_console(console, "\r\n"); if event_status.is_error() || event.is_null() { + if show_errors { + write_console( + console, + "error: failed to create manifest request event\r\n", + ); + } return; } @@ -321,24 +274,19 @@ fn request_manifest( }; let request_status = submit_request_with_retries(boot_services, http_protocol, &mut token); - write_console(console, "http_request_status: "); - write_status(console, request_status); - write_console(console, "\r\n"); if !request_status.is_error() { let completion = poll_http_token(http_protocol, &token); - write_console(console, "http_request_completion: "); - write_status(console, completion); - write_console(console, "\r\n"); if !completion.is_error() { receive_manifest_response(console, boot_services, image, http_protocol); + } else if show_errors { + write_console(console, "error: manifest request did not complete\r\n"); } + } else if show_errors { + write_console(console, "error: failed to send manifest request\r\n"); } - let close_status = (boot_services.close_event)(event); - write_console(console, "http_request_close_event_status: "); - write_status(console, close_status); - write_console(console, "\r\n"); + let _ = (boot_services.close_event)(event); } extern "efiapi" fn noop_event_notify(_event: EfiEvent, _context: *mut c_void) {} @@ -410,10 +358,11 @@ fn receive_manifest_response( core::ptr::null_mut(), &mut event, ); - write_console(console, "http_response_event_status: "); - write_status(console, event_status); - write_console(console, "\r\n"); if event_status.is_error() || event.is_null() { + write_console( + console, + "error: failed to create manifest response event\r\n", + ); return; } @@ -435,15 +384,9 @@ fn receive_manifest_response( }; let response_status = unsafe { ((*http_protocol).response)(http_protocol, &mut token) }; - write_console(console, "http_response_status: "); - write_status(console, response_status); - write_console(console, "\r\n"); if !response_status.is_error() { let completion = poll_http_token(http_protocol, &token); - write_console(console, "http_response_completion: "); - write_status(console, completion); - write_console(console, "\r\n"); if !completion.is_error() { print_manifest_response( console, @@ -454,13 +397,14 @@ fn receive_manifest_response( &message, &body, ); + } else { + write_console(console, "error: manifest response did not complete\r\n"); } + } else { + write_console(console, "error: failed to receive manifest response\r\n"); } - let close_status = (boot_services.close_event)(event); - write_console(console, "http_response_close_event_status: "); - write_status(console, close_status); - write_console(console, "\r\n"); + let _ = (boot_services.close_event)(event); } fn print_manifest_response( @@ -472,56 +416,32 @@ fn print_manifest_response( message: &EfiHttpMessage, body: &[u8], ) { - write_console(console, "http_response_status_enum: "); - write_usize(console, response_data.status_code as usize); - write_console(console, "\r\n"); - write_console(console, "http_response_status_code: "); - write_http_status_code(console, response_data.status_code); - write_console(console, "\r\n"); - - write_console(console, "http_response_header_count: "); - write_usize(console, message.header_count); - write_console(console, "\r\n"); - - write_console(console, "http_response_body_length: "); - write_usize(console, message.body_length); - write_console(console, "\r\n"); - if response_data.status_code != HTTP_STATUS_200_OK { - write_console( - console, - "manifest_parse_skipped: HTTP status is not 200\r\n", - ); + write_console(console, "error: manifest HTTP status "); + write_http_status_code(console, response_data.status_code); + write_console(console, "\r\n"); free_response_headers(boot_services, message); return; } if message.body_length > body.len() { - write_console(console, "manifest_parse_skipped: body buffer too small\r\n"); + write_console(console, "error: manifest body too large\r\n"); free_response_headers(boot_services, message); return; } match parse_downloaded_manifest(&body[..message.body_length], body.len()) { Ok(manifest) => { - write_console(console, "manifest_arch: "); - write_console(console, manifest.arch); - write_console(console, "\r\n"); if !target_matches_manifest(manifest.arch) { - write_console(console, "manifest_arch_rejected: target mismatch\r\n"); + write_console(console, "error: manifest arch mismatch\r\n"); free_response_headers(boot_services, message); return; } - write_console(console, "manifest_kernel_url: "); - write_console(console, manifest.kernel_url); - write_console(console, "\r\n"); - write_console(console, "manifest_kernel_size: "); + write_console(console, "kernel: "); write_usize(console, manifest.kernel_size as usize); - write_console(console, "\r\n"); - write_console(console, "manifest_kernel_load_addr: 0x"); + write_console(console, " bytes load=0x"); write_hex_u64(console, manifest.kernel_load_addr); - write_console(console, "\r\n"); - write_console(console, "manifest_entry_point: 0x"); + write_console(console, " entry=0x"); write_hex_u64(console, manifest.entry_point); write_console(console, "\r\n"); request_kernel_probe( @@ -536,7 +456,7 @@ fn print_manifest_response( manifest.arch, ); } - Err(_) => write_console(console, "manifest_parse_failed\r\n"), + Err(_) => write_console(console, "error: failed to parse manifest\r\n"), } free_response_headers(boot_services, message); @@ -581,27 +501,22 @@ fn request_kernel_range( let url = match write_utf16_nul(kernel_url, &mut url_buffer) { Ok(url) => url, Err(_) => { - write_console(console, "kernel_request_skipped: URL too long\r\n"); + write_console(console, "error: kernel URL too long\r\n"); return None; } }; let mut host_name = *b"Host\0"; let mut host_value = [0u8; HTTP_HOST_BUFFER_SIZE]; - let host = match write_url_host_header_value(kernel_url, &mut host_value) { - Ok(host) => host, + match write_url_host_header_value(kernel_url, &mut host_value) { + Ok(_) => {} Err(()) => { - write_console(console, "kernel_request_skipped: invalid URL host\r\n"); + write_console(console, "error: invalid kernel URL host\r\n"); return None; } }; let mut range_name = *b"Range\0"; let mut range_value = [0u8; 64]; write_range_header_value(range_start, range_end, &mut range_value)?; - if first { - write_console(console, "kernel_request_host: "); - write_console(console, host); - write_console(console, "\r\n"); - } let mut event = core::ptr::null_mut(); let event_status = (boot_services.create_event)( @@ -611,12 +526,8 @@ fn request_kernel_range( core::ptr::null_mut(), &mut event, ); - if first { - write_console(console, "kernel_request_event_status: "); - write_status(console, event_status); - write_console(console, "\r\n"); - } if event_status.is_error() || event.is_null() { + write_console(console, "error: failed to create kernel request event\r\n"); return None; } @@ -650,26 +561,12 @@ fn request_kernel_range( }; let request_status = submit_request_with_retries(boot_services, http_protocol, &mut token); - if first || request_status.is_error() { - write_console(console, "kernel_request_status: "); - write_status(console, request_status); - write_console(console, "\r\n"); - } if !request_status.is_error() { let completion = poll_http_token(http_protocol, &token); - if first || completion.is_error() { - write_console(console, "kernel_request_completion: "); - write_status(console, completion); - write_console(console, "\r\n"); - } if completion.is_error() { - let close_status = (boot_services.close_event)(event); - if first { - write_console(console, "kernel_request_close_event_status: "); - write_status(console, close_status); - write_console(console, "\r\n"); - } + write_console(console, "error: kernel request did not complete\r\n"); + let _ = (boot_services.close_event)(event); return None; } let received = receive_kernel_range_body( @@ -680,21 +577,12 @@ fn request_kernel_range( expected_len, first, ); - let close_status = (boot_services.close_event)(event); - if first { - write_console(console, "kernel_request_close_event_status: "); - write_status(console, close_status); - write_console(console, "\r\n"); - } + let _ = (boot_services.close_event)(event); return received; } - let close_status = (boot_services.close_event)(event); - if first { - write_console(console, "kernel_request_close_event_status: "); - write_status(console, close_status); - write_console(console, "\r\n"); - } + write_console(console, "error: failed to send kernel request\r\n"); + let _ = (boot_services.close_event)(event); None } @@ -724,19 +612,12 @@ fn download_kernel_to_load_addr( page_count, &mut target, ); - write_console(console, "kernel_allocate_pages_status: "); - write_status(console, allocate_status); - write_console(console, "\r\n"); - write_console(console, "kernel_target_addr: 0x"); - write_hex_u64(console, target); - write_console(console, "\r\n"); - write_console(console, "kernel_target_pages: "); - write_usize(console, page_count); - write_console(console, "\r\n"); if allocate_status.is_error() || target != kernel_load_addr { + write_console(console, "error: failed to allocate kernel pages\r\n"); return; } + print_download_progress(console, 0, expected_size, 0); let received = download_kernel_ranges( console, boot_services, @@ -745,24 +626,10 @@ fn download_kernel_to_load_addr( kernel_load_addr, expected_size, ); - let checksum = checksum_add(0, unsafe { - core::slice::from_raw_parts(kernel_load_addr as *const u8, received) - }); let complete = received == expected_size; - write_console(console, "kernel_downloaded_size: "); - write_usize(console, received); - write_console(console, "\r\n"); - write_console(console, "kernel_expected_size: "); - write_usize(console, expected_size); - write_console(console, "\r\n"); - write_console(console, "kernel_download_complete: "); - write_console(console, if complete { "yes\r\n" } else { "no\r\n" }); - write_console(console, "kernel_checksum32: 0x"); - write_hex_u32(console, checksum); - write_console(console, "\r\n"); - if complete { + write_console(console, "\r\n"); print_jump_readiness( console, boot_services, @@ -774,10 +641,9 @@ fn download_kernel_to_load_addr( page_count, ); } else { - let free_status = (boot_services.free_pages)(kernel_load_addr, page_count); - write_console(console, "kernel_free_pages_status: "); - write_status(console, free_status); write_console(console, "\r\n"); + write_console(console, "error: kernel download incomplete\r\n"); + let _ = (boot_services.free_pages)(kernel_load_addr, page_count); } } @@ -834,7 +700,7 @@ fn download_kernel_ranges( expected_size: usize, ) -> usize { let mut downloaded = 0usize; - let mut next_progress = KERNEL_PROGRESS_STEP; + let mut next_progress_percent = KERNEL_PROGRESS_STEP_PERCENT; while downloaded < expected_size { let chunk_len = (expected_size - downloaded).min(KERNEL_RANGE_CHUNK_SIZE); @@ -853,22 +719,23 @@ fn download_kernel_ranges( chunk_len, first, ) else { - write_console(console, "kernel_download_stopped_at: "); + write_console(console, "\r\n"); + write_console(console, "error: kernel download stopped at "); write_usize(console, downloaded); write_console(console, "\r\n"); break; }; if received == 0 { - write_console(console, "kernel_download_stopped: zero length chunk\r\n"); + write_console(console, "\r\n"); + write_console(console, "error: zero length kernel chunk\r\n"); break; } downloaded += received; - if downloaded >= next_progress || downloaded == expected_size { - write_console(console, "kernel_download_progress: "); - write_usize(console, downloaded); - write_console(console, "\r\n"); - while next_progress <= downloaded { - next_progress += KERNEL_PROGRESS_STEP; + let percent = download_percent(downloaded, expected_size); + if percent >= next_progress_percent || downloaded == expected_size { + print_download_progress(console, downloaded, expected_size, percent); + while next_progress_percent <= percent { + next_progress_percent += KERNEL_PROGRESS_STEP_PERCENT; } } } @@ -876,6 +743,61 @@ fn download_kernel_ranges( downloaded } +fn download_percent(downloaded: usize, expected_size: usize) -> usize { + if expected_size == 0 { + return 0; + } + downloaded.saturating_mul(100) / expected_size +} + +fn print_download_progress( + console: *mut EfiSimpleTextOutputProtocol, + downloaded: usize, + expected_size: usize, + percent: usize, +) { + write_console(console, "\rdownload: ["); + let filled = percent.saturating_mul(KERNEL_PROGRESS_BAR_WIDTH) / 100; + for index in 0..KERNEL_PROGRESS_BAR_WIDTH { + write_console(console, if index < filled { "#" } else { "-" }); + } + write_console(console, "] "); + write_usize(console, percent); + write_console(console, "% "); + write_human_size(console, downloaded); + write_console(console, "/"); + write_human_size(console, expected_size); + write_console(console, " "); +} + +fn write_human_size(console: *mut EfiSimpleTextOutputProtocol, bytes: usize) { + const KIB: usize = 1024; + const MIB: usize = 1024 * 1024; + + if bytes >= MIB { + write_fixed_2(console, bytes, MIB); + write_console(console, " MiB"); + } else if bytes >= KIB { + write_fixed_2(console, bytes, KIB); + write_console(console, " KiB"); + } else { + write_usize(console, bytes); + write_console(console, " B"); + } +} + +fn write_fixed_2(console: *mut EfiSimpleTextOutputProtocol, value: usize, unit: usize) { + let whole = value / unit; + let frac = value % unit; + let hundredths = frac.saturating_mul(100) / unit; + write_usize(console, whole); + write_console(console, "."); + if hundredths < 10 { + write_console(console, "0"); + } + write_usize(console, hundredths); +} + fn write_range_header_value(start: usize, end: usize, output: &mut [u8]) -> Option<()> { let mut writer = ByteWriter::new(output); writer.write_bytes(b"bytes=")?; @@ -949,10 +871,9 @@ fn receive_kernel_range_body( let response = receive_kernel_stream_chunk(console, boot_services, http_protocol, body, body_len, first)?; if response.http_status != HTTP_STATUS_206_PARTIAL_CONTENT { - write_console( - console, - "kernel_download_stopped: HTTP status is not 206\r\n", - ); + write_console(console, "error: kernel HTTP status "); + write_http_status_code(console, response.http_status); + write_console(console, "\r\n"); return None; } Some(response.received) @@ -969,7 +890,7 @@ fn receive_kernel_stream_chunk( http_protocol: *mut EfiHttpProtocol, body: *mut u8, body_len: usize, - first: bool, + _first: bool, ) -> Option { let mut event = core::ptr::null_mut(); let event_status = (boot_services.create_event)( @@ -979,12 +900,8 @@ fn receive_kernel_stream_chunk( core::ptr::null_mut(), &mut event, ); - if first { - write_console(console, "kernel_response_event_status: "); - write_status(console, event_status); - write_console(console, "\r\n"); - } if event_status.is_error() || event.is_null() { + write_console(console, "error: failed to create kernel response event\r\n"); return None; } @@ -1007,49 +924,22 @@ fn receive_kernel_stream_chunk( }; let response_status = unsafe { ((*http_protocol).response)(http_protocol, &mut token) }; - if first { - write_console(console, "kernel_response_status: "); - write_status(console, response_status); - write_console(console, "\r\n"); - } else if response_status.is_error() { - write_console(console, "kernel_stream_response_status: "); - write_status(console, response_status); - write_console(console, "\r\n"); - } if response_status.is_error() { - let close_status = (boot_services.close_event)(event); - if first { - write_console(console, "kernel_response_close_event_status: "); - write_status(console, close_status); - write_console(console, "\r\n"); - } + write_console(console, "error: failed to receive kernel response\r\n"); + let _ = (boot_services.close_event)(event); return None; } let completion = poll_http_token(http_protocol, &token); - if first { - write_console(console, "kernel_response_completion: "); - write_status(console, completion); - write_console(console, "\r\n"); - if !completion.is_error() { - print_kernel_chunk_response(console, boot_services, &response_data, &message); - } + if !completion.is_error() { + free_response_headers(boot_services, &message); } else { - if completion.is_error() { - write_console(console, "kernel_stream_response_completion: "); - write_status(console, completion); - write_console(console, "\r\n"); - } + write_console(console, "error: kernel response did not complete\r\n"); free_response_headers(boot_services, &message); } - let close_status = (boot_services.close_event)(event); - if first { - write_console(console, "kernel_response_close_event_status: "); - write_status(console, close_status); - write_console(console, "\r\n"); - } + let _ = (boot_services.close_event)(event); if completion.is_error() { return None; @@ -1070,18 +960,6 @@ fn print_jump_readiness( kernel_size: usize, page_count: usize, ) { - write_console(console, "jump_ready_load_addr: 0x"); - write_hex_u64(console, kernel_load_addr); - write_console(console, "\r\n"); - write_console(console, "jump_ready_entry_point: 0x"); - write_hex_u64(console, entry_point); - write_console(console, "\r\n"); - write_console(console, "jump_ready_kernel_size: "); - write_usize(console, kernel_size); - write_console(console, "\r\n"); - write_console(console, "jump_ready_pages_retained: "); - write_usize(console, page_count); - write_console(console, "\r\n"); print_entry_plan( console, &EntryPlan { @@ -1092,17 +970,7 @@ fn print_jump_readiness( boot_info: 0, }, ); - write_console(console, "boot_jump_enabled: "); - write_console( - console, - if ENABLE_BOOT_JUMP { - "yes\r\n" - } else { - "no\r\n" - }, - ); - probe_memory_map(console, boot_services, image); maybe_exit_boot_services( console, boot_services, @@ -1115,55 +983,8 @@ fn print_jump_readiness( boot_info: 0, }, ); - let free_status = (boot_services.free_pages)(kernel_load_addr, page_count); - write_console(console, "jump_skip_free_pages_status: "); - write_status(console, free_status); - write_console(console, "\r\n"); - write_console( - console, - "jump_skipped: ExitBootServices and entry call pending\r\n", - ); -} - -fn probe_memory_map( - console: *mut EfiSimpleTextOutputProtocol, - boot_services: &mut EfiBootServices, - image: EfiHandle, -) { - let mut probe = MemoryMapProbe::new(); - let size_status = get_memory_map(boot_services, &mut probe, core::ptr::null_mut(), 0); - write_console(console, "memory_map_size_status: "); - write_status(console, size_status); - write_console(console, "\r\n"); - write_console(console, "memory_map_required_size: "); - write_usize(console, probe.memory_map_size); - write_console(console, "\r\n"); - - let mut memory_map = [0u8; MEMORY_MAP_BUFFER_SIZE]; - let map_status = get_memory_map( - boot_services, - &mut probe, - memory_map.as_mut_ptr() as *mut EfiMemoryDescriptor, - memory_map.len(), - ); - write_console(console, "memory_map_status: "); - write_status(console, map_status); - write_console(console, "\r\n"); - write_console(console, "memory_map_size: "); - write_usize(console, probe.memory_map_size); - write_console(console, "\r\n"); - write_console(console, "memory_map_key: "); - write_usize(console, probe.map_key); - write_console(console, "\r\n"); - write_console(console, "memory_map_descriptor_size: "); - write_usize(console, probe.descriptor_size); - write_console(console, "\r\n"); - write_console(console, "memory_map_descriptor_version: "); - write_usize(console, probe.descriptor_version as usize); - write_console(console, "\r\n"); - write_console(console, "exit_boot_services_image: 0x"); - write_hex_usize(console, image as usize); - write_console(console, "\r\n"); + let _ = (boot_services.free_pages)(kernel_load_addr, page_count); + write_console(console, "error: jump returned unexpectedly\r\n"); } struct MemoryMapProbe { @@ -1207,10 +1028,7 @@ fn maybe_exit_boot_services( entry_plan: &EntryPlan<'_>, ) { if !ENABLE_BOOT_JUMP { - write_console( - console, - "exit_boot_services_skipped: boot jump disabled\r\n", - ); + write_console(console, "error: boot jump disabled\r\n"); return; } @@ -1233,23 +1051,11 @@ fn maybe_exit_boot_services( if !exit_status.is_error() { unsafe { call_entry_point(&entry_plan) }; } - write_console(console, "exit_boot_services_status: "); - write_status(console, exit_status); - write_console(console, "\r\n"); retry_exit_boot_services(console, boot_services, image, &entry_plan); return; } - write_console(console, "exit_memory_map_status: "); - write_status(console, map_status); - write_console(console, "\r\n"); - write_console(console, "exit_memory_map_key: "); - write_usize(console, probe.map_key); - write_console(console, "\r\n"); - write_console( - console, - "exit_boot_services_skipped: memory map unavailable\r\n", - ); + write_console(console, "error: memory map unavailable before jump\r\n"); } fn retry_exit_boot_services( @@ -1267,9 +1073,7 @@ fn retry_exit_boot_services( memory_map.len(), ); if map_status.is_error() { - write_console(console, "exit_retry_memory_map_status: "); - write_status(console, map_status); - write_console(console, "\r\n"); + write_console(console, "error: memory map retry failed\r\n"); return; } @@ -1283,9 +1087,7 @@ fn retry_exit_boot_services( if !exit_status.is_error() { unsafe { call_entry_point(&entry_plan) }; } - write_console(console, "exit_retry_boot_services_status: "); - write_status(console, exit_status); - write_console(console, "\r\n"); + write_console(console, "error: ExitBootServices failed\r\n"); } fn populate_boot_info_from_memory_map( @@ -1302,9 +1104,7 @@ fn populate_boot_info_from_memory_map( && offset + core::mem::size_of::() <= memory_map.len() { let descriptor = unsafe { - core::ptr::read_unaligned( - memory_map.as_ptr().add(offset) as *const EfiMemoryDescriptor - ) + core::ptr::read_unaligned(memory_map.as_ptr().add(offset) as *const EfiMemoryDescriptor) }; if descriptor.memory_type == EFI_CONVENTIONAL_MEMORY && boot_info.region_count < OSTOOL_BOOT_INFO_MAX_RAM_REGIONS as u32 @@ -1312,7 +1112,9 @@ fn populate_boot_info_from_memory_map( let index = boot_info.region_count as usize; boot_info.regions[index] = OstoolRamRegion { start: descriptor.physical_start, - size: descriptor.number_of_pages.saturating_mul(EFI_PAGE_SIZE as u64), + size: descriptor + .number_of_pages + .saturating_mul(EFI_PAGE_SIZE as u64), }; boot_info.region_count += 1; } @@ -1320,67 +1122,12 @@ fn populate_boot_info_from_memory_map( } } -fn print_kernel_chunk_response( - console: *mut EfiSimpleTextOutputProtocol, - boot_services: &mut EfiBootServices, - response_data: &EfiHttpResponseData, - message: &EfiHttpMessage, -) { - write_console(console, "kernel_response_status_enum: "); - write_usize(console, response_data.status_code as usize); - write_console(console, "\r\n"); - write_console(console, "kernel_response_status_code: "); - write_http_status_code(console, response_data.status_code); - write_console(console, "\r\n"); - write_console(console, "kernel_response_header_count: "); - write_usize(console, message.header_count); - write_console(console, "\r\n"); - write_console(console, "kernel_response_body_length: "); - write_usize(console, message.body_length); - write_console(console, "\r\n"); - - if response_data.status_code == HTTP_STATUS_200_OK - || response_data.status_code == HTTP_STATUS_206_PARTIAL_CONTENT - { - write_console(console, "kernel_chunk_received\r\n"); - } else { - write_console( - console, - "kernel_download_stopped: unexpected HTTP status\r\n", - ); - } - - free_response_headers(boot_services, message); -} - fn free_response_headers(boot_services: &mut EfiBootServices, message: &EfiHttpMessage) { if !message.headers.is_null() { let _ = (boot_services.free_pool)(message.headers as *mut c_void); } } -fn checksum_add(mut checksum: u32, bytes: &[u8]) -> u32 { - for byte in bytes { - checksum = checksum.wrapping_add(*byte as u32); - } - checksum -} - -fn write_hex_u32(console: *mut EfiSimpleTextOutputProtocol, value: u32) { - let mut output = [0u8; 8]; - let mut shift = 28u32; - for byte in &mut output { - let digit = ((value >> shift) & 0xf) as u8; - *byte = match digit { - 0..=9 => b'0' + digit, - _ => b'a' + (digit - 10), - }; - shift = shift.saturating_sub(4); - } - let text = core::str::from_utf8(&output).unwrap_or("????????"); - write_console(console, text); -} - fn write_hex_u64(console: *mut EfiSimpleTextOutputProtocol, value: u64) { let mut output = [0u8; 16]; let mut shift = 60u32; @@ -1396,14 +1143,6 @@ fn write_hex_u64(console: *mut EfiSimpleTextOutputProtocol, value: u64) { write_console(console, text); } -fn write_hex_usize(console: *mut EfiSimpleTextOutputProtocol, value: usize) { - if usize::BITS == 64 { - write_hex_u64(console, value as u64); - } else { - write_hex_u32(console, value as u32); - } -} - fn write_http_status_code(console: *mut EfiSimpleTextOutputProtocol, status_code: u32) { let numeric = match status_code { 1 => Some(100), @@ -1479,13 +1218,9 @@ fn configure_http_ipv4_default(http_protocol: *mut EfiHttpProtocol) -> EfiStatus } fn destroy_http_child( - console: *mut EfiSimpleTextOutputProtocol, + _console: *mut EfiSimpleTextOutputProtocol, service_binding: *mut EfiServiceBindingProtocol, child_handle: EfiHandle, ) { - let destroy_status = - unsafe { ((*service_binding).destroy_child)(service_binding, child_handle) }; - write_console(console, "http_destroy_child_status: "); - write_status(console, destroy_status); - write_console(console, "\r\n"); + let _ = unsafe { ((*service_binding).destroy_child)(service_binding, child_handle) }; } From 22898e3636b301d62d3be09f52c1bec3bb1fdc08 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 1 Jun 2026 06:31:13 +0000 Subject: [PATCH 38/39] feat: hide cursor during kernel download progress and add remaining TextOutput ABI fields --- httpboot/src/uefi/abi.rs | 8 ++++++++ httpboot/src/uefi/console.rs | 9 +++++++++ httpboot/src/uefi/http.rs | 9 +++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/httpboot/src/uefi/abi.rs b/httpboot/src/uefi/abi.rs index 46a2daa4..99752812 100644 --- a/httpboot/src/uefi/abi.rs +++ b/httpboot/src/uefi/abi.rs @@ -74,6 +74,14 @@ pub struct EfiSimpleTextOutputProtocol { pub reset: usize, pub output_string: extern "efiapi" fn(this: *mut EfiSimpleTextOutputProtocol, string: *const u16) -> EfiStatus, + pub test_string: usize, + pub query_mode: usize, + pub set_mode: usize, + pub set_attribute: usize, + pub clear_screen: usize, + pub set_cursor_position: usize, + pub enable_cursor: + extern "efiapi" fn(this: *mut EfiSimpleTextOutputProtocol, visible: u8) -> EfiStatus, } #[repr(C)] diff --git a/httpboot/src/uefi/console.rs b/httpboot/src/uefi/console.rs index 814e4f95..02407d19 100644 --- a/httpboot/src/uefi/console.rs +++ b/httpboot/src/uefi/console.rs @@ -36,6 +36,15 @@ pub fn write_console(console: *mut EfiSimpleTextOutputProtocol, message: &str) { (console_ref.output_string)(console, buffer.as_ptr()); } +pub fn set_progress_cursor_visible(console: *mut EfiSimpleTextOutputProtocol, visible: bool) { + write_serial(if visible { b"\x1b[?25h" } else { b"\x1b[?25l" }); + + let Some(console_ref) = (unsafe { console.as_mut() }) else { + return; + }; + let _ = (console_ref.enable_cursor)(console, u8::from(visible)); +} + fn write_serial(bytes: &[u8]) { init_com1(); for byte in bytes { diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index 347566b8..196df864 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -11,7 +11,9 @@ use crate::uefi::abi::{ EfiSystemTable, HTTP_METHOD_GET, HTTP_STATUS_200_OK, HTTP_STATUS_206_PARTIAL_CONTENT, HTTP_VERSION_11, TPL_CALLBACK, boot_services_from_system_table, }; -use crate::uefi::console::{write_console, write_usize, write_utf16_nul}; +use crate::uefi::console::{ + set_progress_cursor_visible, write_console, write_usize, write_utf16_nul, +}; use crate::uefi::entry::{EntryPlan, call_entry_point, print_entry_plan, target_matches_manifest}; use httpboot::parse_downloaded_manifest; @@ -23,7 +25,7 @@ const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; const HTTP_REQUEST_RETRY_LIMIT: usize = 8; const HTTP_REQUEST_RETRY_STALL_US: usize = 250_000; const HTTP_BOOT_ROUND_RETRY_STALL_US: usize = 3_000_000; -const KERNEL_PROGRESS_STEP_PERCENT: usize = 5; +const KERNEL_PROGRESS_STEP_PERCENT: usize = 1; const KERNEL_PROGRESS_BAR_WIDTH: usize = 80; const MAX_KERNEL_DOWNLOAD_SIZE: usize = 256 * 1024 * 1024; const EFI_PAGE_SIZE: usize = 4096; @@ -617,6 +619,7 @@ fn download_kernel_to_load_addr( return; } + set_progress_cursor_visible(console, false); print_download_progress(console, 0, expected_size, 0); let received = download_kernel_ranges( console, @@ -629,6 +632,7 @@ fn download_kernel_to_load_addr( let complete = received == expected_size; if complete { + set_progress_cursor_visible(console, true); write_console(console, "\r\n"); print_jump_readiness( console, @@ -641,6 +645,7 @@ fn download_kernel_to_load_addr( page_count, ); } else { + set_progress_cursor_visible(console, true); write_console(console, "\r\n"); write_console(console, "error: kernel download incomplete\r\n"); let _ = (boot_services.free_pages)(kernel_load_addr, page_count); From d8e35a155f0e91a7dd5810d2b0165c2f94da00f9 Mon Sep 17 00:00:00 2001 From: Josen-B Date: Mon, 1 Jun 2026 08:54:40 +0000 Subject: [PATCH 39/39] docs: add comment explaining ASUS NUC15 firmware HTTP range chunk size --- httpboot/src/uefi/http.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/httpboot/src/uefi/http.rs b/httpboot/src/uefi/http.rs index 196df864..98084130 100644 --- a/httpboot/src/uefi/http.rs +++ b/httpboot/src/uefi/http.rs @@ -20,6 +20,11 @@ use httpboot::parse_downloaded_manifest; const UTF16_URL_BUFFER_SIZE: usize = 1024; const HTTP_HOST_BUFFER_SIZE: usize = 256; const MANIFEST_BODY_BUFFER_SIZE: usize = 4096; +// Keep kernel downloads range-based because the ASUS NUC15 UEFI HTTP stack can +// time out when one large response body is drained through repeated Response() +// calls. The NUC15 firmware currently completes 1 KiB range responses reliably, +// while larger ranges may require draining one HTTP response with multiple +// Response() calls and can fail in firmware. const KERNEL_RANGE_CHUNK_SIZE: usize = 1024; const HTTP_COMPLETION_POLL_LIMIT: usize = 100_000; const HTTP_REQUEST_RETRY_LIMIT: usize = 8; @@ -873,8 +878,14 @@ fn receive_kernel_range_body( body_len: usize, first: bool, ) -> Option { - let response = - receive_kernel_stream_chunk(console, boot_services, http_protocol, body, body_len, first)?; + let response = receive_kernel_stream_chunk( + console, + boot_services, + http_protocol, + body, + body_len, + first, + )?; if response.http_status != HTTP_STATUS_206_PARTIAL_CONTENT { write_console(console, "error: kernel HTTP status "); write_http_status_code(console, response.http_status);