mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-11 18:49:24 +00:00
151 lines
4.4 KiB
C++
151 lines
4.4 KiB
C++
//---------------------------------------------------------------------------
|
|
//
|
|
// SCSI Target Emulator PiSCSI
|
|
// for Raspberry Pi
|
|
//
|
|
// Copyright (C) 2024 akuker
|
|
//
|
|
// [ Detect Raspberry Pi version information ]
|
|
//
|
|
// The Raspberry Pi version detection is based upon the example code
|
|
// provided by the Raspberry Pi foundation:
|
|
// https://github.com/raspberrypi/documentation/blob/develop/documentation/asciidoc/computers/raspberry-pi/revision-codes.adoc
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
#include <cstdint>
|
|
#include <stdio.h>
|
|
#include <string>
|
|
#include <type_traits>
|
|
|
|
using namespace std;
|
|
|
|
//===========================================================================
|
|
//
|
|
// Raspberry Pi Revision Information
|
|
//
|
|
// With the launch of the Raspberry Pi 2, new-style revision codes were
|
|
// introduced. Rather than being sequential, each bit of the hex code
|
|
// represents a piece of information about the revision.
|
|
//
|
|
//===========================================================================
|
|
|
|
class Rpi_Revision_Code {
|
|
public:
|
|
enum class memory_size_type : uint8_t {
|
|
MEM_256MB = 0,
|
|
MEM_512MB = 1,
|
|
MEM_1GB = 2,
|
|
MEM_2GB = 3,
|
|
MEM_4GB = 4,
|
|
MEM_8GB = 5,
|
|
MEM_INVALID = 0x7,
|
|
};
|
|
bool valid_memory_size_type(memory_size_type value) {
|
|
return (value >= memory_size_type::MEM_256MB &&
|
|
value <= memory_size_type::MEM_8GB);
|
|
}
|
|
enum class manufacturer_type : uint8_t {
|
|
SonyUK = 0,
|
|
Egoman = 1,
|
|
Embest2 = 2,
|
|
SonyJapan = 3,
|
|
Embest4 = 4,
|
|
Stadium = 5,
|
|
MANUFACTURER_INVALID = 0xF,
|
|
};
|
|
|
|
bool valid_manufacturer_type(manufacturer_type value) {
|
|
return (value >= manufacturer_type::SonyUK &&
|
|
value <= manufacturer_type::Stadium);
|
|
}
|
|
|
|
enum class cpu_type : uint8_t {
|
|
BCM2835 = 0,
|
|
BCM2836 = 1,
|
|
BCM2837 = 2,
|
|
BCM2711 = 3,
|
|
BCM2712 = 4,
|
|
CPU_TYPE_INVALID = 0xF,
|
|
};
|
|
bool valid_cpu_type(cpu_type value) {
|
|
return (value >= cpu_type::BCM2835 && value <= cpu_type::BCM2712);
|
|
}
|
|
|
|
enum class rpi_version_type : uint8_t {
|
|
rpi_version_A = 0,
|
|
rpi_version_B = 1,
|
|
rpi_version_Aplus = 2,
|
|
rpi_version_Bplus = 3,
|
|
rpi_version_2B = 4,
|
|
rpi_version_Alpha = 5, // (early prototype)
|
|
rpi_version_CM1 = 6,
|
|
rpi_version_3B = 8,
|
|
rpi_version_Zero = 9,
|
|
rpi_version_CM3 = 0xa,
|
|
rpi_version_ZeroW = 0xc,
|
|
rpi_version_3Bplus = 0xd,
|
|
rpi_version_3Aplus = 0xe,
|
|
rpi_version_InternalUseOnly1 = 0xf,
|
|
rpi_version_CM3plus = 0x10,
|
|
rpi_version_4B = 0x11,
|
|
rpi_version_Zero2W = 0x12,
|
|
rpi_version_400 = 0x13,
|
|
rpi_version_CM4 = 0x14,
|
|
rpi_version_CM4S = 0x15,
|
|
rpi_version_InternalUseOnly2 = 0x16,
|
|
rpi_version_5 = 0x17,
|
|
rpi_version_invalid = 0xFF
|
|
};
|
|
bool valid_rpi_version_type(rpi_version_type value) {
|
|
return (value >= rpi_version_type::rpi_version_A &&
|
|
value <= rpi_version_type::rpi_version_5);
|
|
}
|
|
|
|
public:
|
|
Rpi_Revision_Code(const std::string &cpuinfo_path = "/proc/cpuinfo");
|
|
Rpi_Revision_Code(uint32_t value) : rpi_revcode(value){};
|
|
~Rpi_Revision_Code() = default;
|
|
|
|
private:
|
|
uint32_t extract_bits(int start_bit, int size);
|
|
|
|
public:
|
|
uint8_t Revision() {
|
|
return (uint8_t)extract_bits(0, 4);
|
|
} //: 4; // (bits 0-3)
|
|
rpi_version_type Type() {
|
|
return (rpi_version_type)extract_bits(4, 8);
|
|
} //: // (bits 4-11)
|
|
cpu_type Processor() { return (cpu_type)extract_bits(12, 4); } // (bits 12-15)
|
|
manufacturer_type Manufacturer() {
|
|
return (manufacturer_type)extract_bits(16, 4);
|
|
} // (bits 16-19)
|
|
memory_size_type MemorySize() {
|
|
return (memory_size_type)extract_bits(20, 3);
|
|
} // (bits 20-22)
|
|
// 1: new-style revision
|
|
// 0: old-style revision
|
|
bool NewStyle() { return (bool)extract_bits(23, 1); } // (bit 23)
|
|
// 0: Warranty is intact
|
|
// 1: Warranty has been voided by overclocking
|
|
bool Waranty() { return (bool)extract_bits(25, 1); } // (bit 25)
|
|
// 0: OTP reading allowed
|
|
// 1: OTP reading disallowed
|
|
bool OtpRead() { return (bool)extract_bits(29, 1); } // (bit 29)
|
|
// 0: OTP programming allowed
|
|
// 1: OTP programming disallowed
|
|
bool OtpProgram() { return (bool)extract_bits(30, 1); } // (bit 30)
|
|
// 0: Overvoltage allowed
|
|
// 1: Overvoltage disallowed
|
|
bool Overvoltage() { return (bool)extract_bits(31, 3); } // (bit 31)
|
|
|
|
bool IsValid() { return is_valid; }
|
|
void SetValid(bool val) { is_valid = val; }
|
|
|
|
private:
|
|
uint32_t rpi_revcode;
|
|
bool is_valid = true;
|
|
};
|