mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-01 05:49:10 +00:00
git subrepo clone --branch=develop https://github.com/m4xw/emuMMC emummc
subrepo: subdir: "emummc" merged: "e72e8f1c" upstream: origin: "https://github.com/m4xw/emuMMC" branch: "develop" commit: "e72e8f1c" git-subrepo: version: "0.4.0" origin: "https://github.com/ingydotnet/git-subrepo" commit: "5d6aba9"
This commit is contained in:
parent
87a1aa17a7
commit
b7a370b156
90 changed files with 21714 additions and 0 deletions
9
emummc/.gitignore
vendored
Normal file
9
emummc/.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
*.kip
|
||||
*.data
|
||||
*.elf
|
||||
build
|
||||
.vscode/ipch
|
||||
.vscode/settings.json
|
||||
*.exe
|
||||
*.kip*
|
||||
emummc.caps
|
12
emummc/.gitrepo
Normal file
12
emummc/.gitrepo
Normal file
|
@ -0,0 +1,12 @@
|
|||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = https://github.com/m4xw/emuMMC
|
||||
branch = develop
|
||||
commit = e72e8f1c8fb7ad8fe7cdedc3784729ea8e11f927
|
||||
parent = 87a1aa17a7693ef39ffea91ad0fa1b530f278bb0
|
||||
method = rebase
|
||||
cmdver = 0.4.0
|
35
emummc/.vscode/c_cpp_properties.json
vendored
Normal file
35
emummc/.vscode/c_cpp_properties.json
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Switch",
|
||||
"includePath": [
|
||||
"/opt/devkitpro/devkitA64/aarch64-none-elf/include",
|
||||
"/opt/devkitpro/devkitA64/lib/gcc/aarch64-none-elf/8.3.0/include",
|
||||
"${workspaceFolder}/libnx-patched/nx/include",
|
||||
"/opt/devkitpro/portlibs/switch/include",
|
||||
"/opt/devkitpro/portlibs/switch/include/freetype2",
|
||||
"${workspaceFolder}/source",
|
||||
"${workspaceFolder}/source/emmc",
|
||||
"${workspaceFolder}/source/libs/fatfs",
|
||||
"${workspaceFolder}/source/power",
|
||||
"${workspaceFolder}/source/soc",
|
||||
"${workspaceFolder}/source/utils",
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE",
|
||||
"__aarch64__",
|
||||
"__SWITCH__",
|
||||
"INNER_HEAP_SIZE=0x80000"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.17763.0",
|
||||
"compilerPath": "/opt/devkitpro/devkitA64/bin/aarch64-none-elf-gcc",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++11",
|
||||
"intelliSenseMode": "gcc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
339
emummc/LICENSE
Normal file
339
emummc/LICENSE
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
114
emummc/Makefile
Normal file
114
emummc/Makefile
Normal file
|
@ -0,0 +1,114 @@
|
|||
.SUFFIXES:
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TARGET := emummc
|
||||
BUILD := build
|
||||
SOURCES := source/nx source source/utils source/emmc source/soc source/power source/emuMMC source/FS source/libs/fatfs
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
EXEFS_SRC := exefs_src
|
||||
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
EMUMMCDIR ?= $(CURDIR)
|
||||
else
|
||||
EMUMMCDIR ?= $(CURDIR)/../
|
||||
endif
|
||||
|
||||
include $(EMUMMCDIR)/nx/switch_rules
|
||||
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
DEFINES := -DINNER_HEAP_SIZE=0x80000
|
||||
|
||||
CFLAGS := -Wall -O2 -ffunction-sections -Wno-unused-function \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(EMUMMCDIR)/nx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(EMUMMCDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
export LD := $(CC)
|
||||
else
|
||||
export LD := $(CXX)
|
||||
endif
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)
|
||||
|
||||
ifeq ($(strip $(CONFIG_JSON)),)
|
||||
jsons := $(wildcard *.json)
|
||||
ifneq (,$(findstring $(TARGET).json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/$(TARGET).json
|
||||
else
|
||||
ifneq (,$(findstring config.json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/config.json
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
all: $(BUILD)
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(TARGET).elf $(TARGET).kip
|
||||
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
all : $(OUTPUT).kip
|
||||
|
||||
$(OUTPUT).kip : $(OUTPUT).elf
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
%.bin.o %_bin.h : %.bin
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
endif
|
36
emummc/README.md
Normal file
36
emummc/README.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
# emuMMC
|
||||
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||
|
||||
### Supported Horizon Versions
|
||||
**1.0.0 - 8.0.1**
|
||||
|
||||
## Features
|
||||
* Arbitrary SDMMC backend selection
|
||||
**This allows loading eMMC from SD or even SD from eMMC**
|
||||
* On the fly hooking / patching, fully self-infesting
|
||||
**Only one payload required for all versions!**
|
||||
* File-based SDMMC backend support (from SD)
|
||||
**This allows loading eMMC images from hekate-backups (split or not)**
|
||||
* SDMMC device based sector offset (*currently eMMC only*)
|
||||
**Raw partition support for eMMC from SD with less performance overhead**
|
||||
* Full support for `/Nintendo` folder redirection to a arbitrary path
|
||||
**No 8 char length restriction!**
|
||||
* exosphere based context configuration
|
||||
**This includes full support for multiple emuMMC images**
|
||||
|
||||
## Compiling
|
||||
### hekate
|
||||
Run `./build.sh` and copy the produced kipm (Kernel Initial Process Modification) file to `/bootloader/sys/`
|
||||
|
||||
### Atmosphere
|
||||
Run `make`, the resulting kip can be used for code injection via fusee (place at `/atmosphere/emummc.kip`)
|
||||
|
||||
## License
|
||||
**emuMMC is released as GPLv2**
|
||||
|
||||
## Credits
|
||||
* **CTCaer** - The CTCaer hekate fork, file-based emuMMC support, SDMMC driver fixes among other things
|
||||
* **SciresM, hexkyz** - The Atmosphere project, FS offsets, additional research related to newer FS versions
|
||||
* **naehrwert** - The hekate project, its SDMMC driver and being very helpful in the early research phase
|
||||
* **jakibaki** - KIP Inject PoC, used in the early dev phase
|
||||
* **switchbrew/devkitPro** - devkitA64 and libnx sources
|
9
emummc/build.sh
Normal file
9
emummc/build.sh
Normal file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
make clean
|
||||
make -j
|
||||
./hactool.exe -t kip emummc.kip --uncompressed emummc_unpacked.kip
|
||||
python2.7 tools/kip1converter.py emummc_unpacked.kip emummc.data
|
||||
cat emummc.caps emummc.data > emummc.kipm
|
132
emummc/emummc.json
Normal file
132
emummc/emummc.json
Normal file
|
@ -0,0 +1,132 @@
|
|||
{
|
||||
"name": "FS",
|
||||
"title_id": "0x0100000000000000",
|
||||
"main_thread_stack_size": "0x00008000",
|
||||
"main_thread_priority": 45,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 1,
|
||||
"kernel_capabilities": [
|
||||
{
|
||||
"type": "map_page",
|
||||
"value": "0x60006000"
|
||||
},
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x6000D000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x700b0000",
|
||||
"is_ro": false,
|
||||
"size": "0x00005000",
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x7000C000",
|
||||
"is_ro": false,
|
||||
"size": "0x00002000",
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x70000000",
|
||||
"is_ro": false,
|
||||
"size": "0x00004000",
|
||||
"is_io": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "handle_table_size",
|
||||
"value": 256
|
||||
},
|
||||
{
|
||||
"type": "irq_pair",
|
||||
"value": [
|
||||
46,
|
||||
47
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "irq_pair",
|
||||
"value": [
|
||||
51,
|
||||
63
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "syscalls",
|
||||
"value": {
|
||||
"svcSetHeapSize": "0x01",
|
||||
"svcSetMemoryPermission": "0x02",
|
||||
"svcSetMemoryAttribute": "0x03",
|
||||
"svcMapMemory": "0x04",
|
||||
"svcUnmapMemory": "0x05",
|
||||
"svcQueryMemory": "0x06",
|
||||
"svcExitProcess": "0x07",
|
||||
"svcCreateThread": "0x08",
|
||||
"svcStartThread": "0x09",
|
||||
"svcExitThread": "0x0a",
|
||||
"svcSleepThread": "0x0b",
|
||||
"svcGetThreadPriority": "0x0c",
|
||||
"svcSetThreadPriority": "0x0d",
|
||||
"svcGetThreadCoreMask": "0x0e",
|
||||
"svcSetThreadCoreMask": "0x0f",
|
||||
"svcGetCurrentProcessorNumber": "0x10",
|
||||
"svcSignalEvent": "0x11",
|
||||
"svcClearEvent": "0x12",
|
||||
"svcMapSharedMemory": "0x13",
|
||||
"svcUnmapSharedMemory": "0x14",
|
||||
"svcCreateTransferMemory": "0x15",
|
||||
"svcCloseHandle": "0x16",
|
||||
"svcResetSignal": "0x17",
|
||||
"svcWaitSynchronization": "0x18",
|
||||
"svcCancelSynchronization": "0x19",
|
||||
"svcArbitrateLock": "0x1a",
|
||||
"svcArbitrateUnlock": "0x1b",
|
||||
"svcWaitProcessWideKeyAtomic": "0x1c",
|
||||
"svcSignalProcessWideKey": "0x1d",
|
||||
"svcGetSystemTick": "0x1e",
|
||||
"svcConnectToNamedPort": "0x1f",
|
||||
"svcSendSyncRequestLight": "0x20",
|
||||
"svcSendSyncRequest": "0x21",
|
||||
"svcSendSyncRequestWithUserBuffer": "0x22",
|
||||
"svcSendAsyncRequestWithUserBuffer": "0x23",
|
||||
"svcGetProcessId": "0x24",
|
||||
"svcGetThreadId": "0x25",
|
||||
"svcBreak": "0x26",
|
||||
"svcOutputDebugString": "0x27",
|
||||
"svcReturnFromException": "0x28",
|
||||
"svcGetInfo": "0x29",
|
||||
"svcWaitForAddress": "0x34",
|
||||
"svcSignalToAddress": "0x35",
|
||||
"svcCreateSession": "0x40",
|
||||
"svcAcceptSession": "0x41",
|
||||
"svcReplyAndReceiveLight": "0x42",
|
||||
"svcReplyAndReceive": "0x43",
|
||||
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
||||
"svcCreateEvent": "0x45",
|
||||
"svcCreateInterruptEvent": "0x53",
|
||||
"svcQueryIoMapping": "0x55",
|
||||
"svcCreateDeviceAddressSpace": "0x56",
|
||||
"svcAttachDeviceAddressSpace": "0x57",
|
||||
"svcDetachDeviceAddressSpace": "0x58",
|
||||
"svcMapDeviceAddressSpaceAligned": "0x5a",
|
||||
"svcUnmapDeviceAddressSpace": "0x5c",
|
||||
"svcGetSystemInfo": "0x6f",
|
||||
"svcSetProcessMemoryPermission": "0x73",
|
||||
"svcCallSecureMonitor": "0x7f"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
229
emummc/nx/switch.ld
Normal file
229
emummc/nx/switch.ld
Normal file
|
@ -0,0 +1,229 @@
|
|||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
code PT_LOAD FLAGS(5) /* Read | Execute */;
|
||||
rodata PT_LOAD FLAGS(4) /* Read */;
|
||||
data PT_LOAD FLAGS(6) /* Read | Write */;
|
||||
dyn PT_DYNAMIC;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* =========== CODE section =========== */
|
||||
PROVIDE(__start__ = 0x0);
|
||||
. = __start__;
|
||||
__code_start = . ;
|
||||
|
||||
/*.trampoline :
|
||||
{
|
||||
KEEP (*(.trampoline))
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.emuMMC_ctx :
|
||||
{
|
||||
KEEP (*(.emuMMC_ctx))
|
||||
. = ALIGN(8);
|
||||
} :code */
|
||||
|
||||
.crt0 :
|
||||
{
|
||||
KEEP (*(.crt0))
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.init :
|
||||
{
|
||||
KEEP( *(.init) )
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.plt :
|
||||
{
|
||||
*(.plt)
|
||||
*(.iplt)
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP( *(.fini) )
|
||||
. = ALIGN(8);
|
||||
} :code
|
||||
|
||||
/* =========== RODATA section =========== */
|
||||
. = ALIGN(0x1000);
|
||||
__rodata_start = . ;
|
||||
|
||||
.nx-module-name : { KEEP (*(.nx-module-name)) } :rodata
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
. = ALIGN(8);
|
||||
} :rodata
|
||||
|
||||
.eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } :rodata
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } :rodata
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } :rodata
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } : rodata
|
||||
|
||||
.dynamic : { *(.dynamic) } :rodata :dyn
|
||||
.dynsym : { *(.dynsym) } :rodata
|
||||
.dynstr : { *(.dynstr) } :rodata
|
||||
.rela.dyn : { *(.rela.*) } :rodata
|
||||
.interp : { *(.interp) } :rodata
|
||||
.hash : { *(.hash) } :rodata
|
||||
.gnu.hash : { *(.gnu.hash) } :rodata
|
||||
.gnu.version : { *(.gnu.version) } :rodata
|
||||
.gnu.version_d : { *(.gnu.version_d) } :rodata
|
||||
.gnu.version_r : { *(.gnu.version_r) } :rodata
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) } :rodata
|
||||
|
||||
/* =========== DATA section =========== */
|
||||
. = ALIGN(0x1000);
|
||||
__data_start = . ;
|
||||
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } :data
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } :data
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } : data
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } :data
|
||||
|
||||
.tdata ALIGN(8) :
|
||||
{
|
||||
__tdata_lma = .;
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
. = ALIGN(8);
|
||||
__tdata_lma_end = .;
|
||||
} :data
|
||||
|
||||
.tbss ALIGN(8) :
|
||||
{
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
|
||||
. = ALIGN(8);
|
||||
} :data
|
||||
|
||||
.preinit_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
} :data
|
||||
|
||||
.init_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE (__init_array_end = .);
|
||||
} :data
|
||||
|
||||
.fini_array ALIGN(8) :
|
||||
{
|
||||
PROVIDE (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE (__fini_array_end = .);
|
||||
} :data
|
||||
|
||||
.ctors ALIGN(8) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
} :data
|
||||
|
||||
.dtors ALIGN(8) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
} :data
|
||||
|
||||
__got_start__ = .;
|
||||
|
||||
.got : { *(.got) *(.igot) } :data
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) } :data
|
||||
|
||||
__got_end__ = .;
|
||||
|
||||
.data ALIGN(8) :
|
||||
{
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
} :data
|
||||
|
||||
__bss_start__ = .;
|
||||
.bss ALIGN(8) :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(8);
|
||||
|
||||
/* Reserve space for the TLS segment of the main thread */
|
||||
__tls_start = .;
|
||||
. += + SIZEOF(.tdata) + SIZEOF(.tbss);
|
||||
__tls_end = .;
|
||||
} : data
|
||||
__bss_end__ = .;
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
__end__ = ABSOLUTE(.) ;
|
||||
|
||||
PROVIDE(__injected_size__ = (__end__ - __start__));
|
||||
|
||||
/* ==================
|
||||
==== Metadata ====
|
||||
================== */
|
||||
|
||||
/* Discard sections that difficult post-processing */
|
||||
/DISCARD/ : { *(.group .comment .note) }
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
}
|
8
emummc/nx/switch.specs
Normal file
8
emummc/nx/switch.specs
Normal file
|
@ -0,0 +1,8 @@
|
|||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T %:getenv(PWD /nx/switch.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak --build-id=sha1 --nx-module-name
|
||||
|
||||
*startfile:
|
||||
crti%O%s crtbegin%O%s
|
||||
|
81
emummc/nx/switch_rules
Normal file
81
emummc/nx/switch_rules
Normal file
|
@ -0,0 +1,81 @@
|
|||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro)
|
||||
endif
|
||||
|
||||
include $(DEVKITPRO)/devkitA64/base_rules
|
||||
|
||||
PORTLIBS := $(PORTLIBS_PATH)/switch
|
||||
PATH := $(PORTLIBS)/bin:$(PATH)
|
||||
|
||||
LIBNX ?= $(DEVKITPRO)/libnx
|
||||
|
||||
ifeq ($(strip $(APP_TITLE)),)
|
||||
APP_TITLE := $(notdir $(OUTPUT))
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(APP_AUTHOR)),)
|
||||
APP_AUTHOR := Unspecified Author
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(APP_VERSION)),)
|
||||
APP_VERSION := 1.0.0
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(APP_ICON)),)
|
||||
APP_ICON := $(LIBNX)/default_icon.jpg
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.nacp: $(MAKEFILE_LIST)
|
||||
@nacptool --create "$(APP_TITLE)" "$(APP_AUTHOR)" "$(APP_VERSION)" $@ $(NACPFLAGS)
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.npdm: $(APP_JSON)
|
||||
@npdmtool $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
define make_pfs0
|
||||
@mkdir -p exefs
|
||||
@[ $(BUILD_EXEFS_SRC) ] && [ -d $(BUILD_EXEFS_SRC) ] && cp -R $(BUILD_EXEFS_SRC)/* exefs || echo > /dev/null
|
||||
@cp $*.nso exefs/main
|
||||
@[ $(APP_JSON) ] && cp $*.npdm exefs/main.npdm || echo > /dev/null
|
||||
@build_pfs0 exefs $@
|
||||
@echo built ... $(notdir $@)
|
||||
endef
|
||||
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
%.pfs0: %.nso
|
||||
else
|
||||
%.pfs0: %.nso %.npdm
|
||||
endif
|
||||
$(make_pfs0)
|
||||
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
%.nsp: %.nso
|
||||
else
|
||||
%.nsp: %.nso %.npdm
|
||||
endif
|
||||
$(make_pfs0)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.nso: %.elf
|
||||
@elf2nso $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.nro: %.elf
|
||||
@elf2nro $< $@ $(NROFLAGS)
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.kip: %.elf
|
||||
@elf2kip $< $(APP_JSON) $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%.elf:
|
||||
@echo linking $(notdir $@)
|
||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
@$(NM) -CSn $@ > $(notdir $*.lst)
|
40
emummc/source/FS/FS.h
Normal file
40
emummc/source/FS/FS.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FS_H__
|
||||
#define __FS_H__
|
||||
|
||||
// TODO
|
||||
#include "../emmc/sdmmc_t210.h"
|
||||
|
||||
#include "FS_versions.h"
|
||||
#include "FS_offsets.h"
|
||||
#include "FS_structs.h"
|
||||
|
||||
#define FS_SDMMC_EMMC 0
|
||||
#define FS_SDMMC_SD 1
|
||||
#define FS_SDMMC_GC 2
|
||||
|
||||
#define FS_EMMC_PARTITION_GPP 0
|
||||
#define FS_EMMC_PARTITION_BOOT0 1
|
||||
#define FS_EMMC_PARTITION_BOOT1 2
|
||||
#define FS_EMMC_PARTITION_INVALID 3
|
||||
|
||||
#define BOOT_PARTITION_SIZE 0x2000
|
||||
#define FS_READ_WRITE_ERROR 1048
|
||||
|
||||
#endif /* __FS_H__ */
|
143
emummc/source/FS/FS_offsets.c
Normal file
143
emummc/source/FS/FS_offsets.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "FS_offsets.h"
|
||||
#include "offsets/100.h"
|
||||
#include "offsets/200.h"
|
||||
#include "offsets/200_exfat.h"
|
||||
#include "offsets/210.h"
|
||||
#include "offsets/210_exfat.h"
|
||||
#include "offsets/300.h"
|
||||
#include "offsets/300_exfat.h"
|
||||
#include "offsets/301.h"
|
||||
#include "offsets/301_exfat.h"
|
||||
#include "offsets/400.h"
|
||||
#include "offsets/400_exfat.h"
|
||||
#include "offsets/410.h"
|
||||
#include "offsets/410_exfat.h"
|
||||
#include "offsets/500.h"
|
||||
#include "offsets/500_exfat.h"
|
||||
#include "offsets/510.h"
|
||||
#include "offsets/510_exfat.h"
|
||||
#include "offsets/600.h"
|
||||
#include "offsets/600_exfat.h"
|
||||
#include "offsets/700.h"
|
||||
#include "offsets/700_exfat.h"
|
||||
#include "offsets/800.h"
|
||||
#include "offsets/800_exfat.h"
|
||||
#include "../utils/fatal.h"
|
||||
|
||||
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
||||
|
||||
#define DEFINE_OFFSET_STRUCT(vers) \
|
||||
static const fs_offsets_t GET_OFFSET_STRUCT_NAME(vers) = { \
|
||||
.sdmmc_accessor_gc = FS_OFFSET##vers##_SDMMC_ACCESSOR_GC, \
|
||||
.sdmmc_accessor_sd = FS_OFFSET##vers##_SDMMC_ACCESSOR_SD, \
|
||||
.sdmmc_accessor_nand = FS_OFFSET##vers##_SDMMC_ACCESSOR_NAND, \
|
||||
.sdmmc_wrapper_read = FS_OFFSET##vers##_SDMMC_WRAPPER_READ, \
|
||||
.sdmmc_wrapper_write = FS_OFFSET##vers##_SDMMC_WRAPPER_WRITE, \
|
||||
.clkrst_set_min_v_clock_rate = FS_OFFSET##vers##_CLKRST_SET_MIN_V_CLK_RATE, \
|
||||
.rtld = FS_OFFSET##vers##_RTLD, \
|
||||
.rtld_destination = FS_OFFSET##vers##_RTLD_DESTINATION, \
|
||||
.lock_mutex = FS_OFFSET##vers##_LOCK_MUTEX, \
|
||||
.unlock_mutex = FS_OFFSET##vers##_UNLOCK_MUTEX, \
|
||||
.sd_mutex = FS_OFFSET##vers##_SD_MUTEX, \
|
||||
.nand_mutex = FS_OFFSET##vers##_NAND_MUTEX, \
|
||||
.active_partition = FS_OFFSET##vers##_ACTIVE_PARTITION, \
|
||||
.sdmmc_das_handle = FS_OFFSET##vers##_SDMMC_DAS_HANDLE, \
|
||||
.shutdown_sd = FS_OFFSET##vers##_SHUTDOWN_SD, \
|
||||
.sd_das_init = FS_OFFSET##vers##_SD_DAS_INIT, \
|
||||
.nintendo_paths = FS_OFFSET##vers##_NINTENDO_PATHS, \
|
||||
}
|
||||
|
||||
// Actually define offset structs
|
||||
DEFINE_OFFSET_STRUCT(_100);
|
||||
DEFINE_OFFSET_STRUCT(_200);
|
||||
DEFINE_OFFSET_STRUCT(_200_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_210);
|
||||
DEFINE_OFFSET_STRUCT(_210_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_300);
|
||||
DEFINE_OFFSET_STRUCT(_300_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_301);
|
||||
DEFINE_OFFSET_STRUCT(_301_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_400);
|
||||
DEFINE_OFFSET_STRUCT(_400_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_410);
|
||||
DEFINE_OFFSET_STRUCT(_410_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_500);
|
||||
DEFINE_OFFSET_STRUCT(_500_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_510);
|
||||
DEFINE_OFFSET_STRUCT(_510_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_600);
|
||||
DEFINE_OFFSET_STRUCT(_600_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_700);
|
||||
DEFINE_OFFSET_STRUCT(_700_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_800);
|
||||
DEFINE_OFFSET_STRUCT(_800_EXFAT);
|
||||
|
||||
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
switch (version) {
|
||||
case FS_VER_1_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_100));
|
||||
case FS_VER_2_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_200));
|
||||
case FS_VER_2_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_200_EXFAT));
|
||||
case FS_VER_2_1_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_210));
|
||||
case FS_VER_2_1_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_210_EXFAT));
|
||||
case FS_VER_3_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_300));
|
||||
case FS_VER_3_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_300_EXFAT));
|
||||
case FS_VER_3_0_1:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_301));
|
||||
case FS_VER_3_0_1_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_301_EXFAT));
|
||||
case FS_VER_4_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_400));
|
||||
case FS_VER_4_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_400_EXFAT));
|
||||
case FS_VER_4_1_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_410));
|
||||
case FS_VER_4_1_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_410_EXFAT));
|
||||
case FS_VER_5_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_500));
|
||||
case FS_VER_5_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_500_EXFAT));
|
||||
case FS_VER_5_1_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_510));
|
||||
case FS_VER_5_1_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_510_EXFAT));
|
||||
case FS_VER_6_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_600));
|
||||
case FS_VER_6_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_600_EXFAT));
|
||||
case FS_VER_7_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_700));
|
||||
case FS_VER_7_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_700_EXFAT));
|
||||
case FS_VER_8_0_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_800));
|
||||
case FS_VER_8_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_800_EXFAT));
|
||||
default:
|
||||
fatal_abort(Fatal_UnknownVersion);
|
||||
}
|
||||
}
|
57
emummc/source/FS/FS_offsets.h
Normal file
57
emummc/source/FS/FS_offsets.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FS_OFFSETS_H__
|
||||
#define __FS_OFFSETS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "FS_versions.h"
|
||||
|
||||
typedef struct {
|
||||
int opcode_reg;
|
||||
uint32_t adrp_offset;
|
||||
} fs_offsets_nintendo_path_t;
|
||||
|
||||
typedef struct {
|
||||
// Accessor vtable getters
|
||||
uintptr_t sdmmc_accessor_gc;
|
||||
uintptr_t sdmmc_accessor_sd;
|
||||
uintptr_t sdmmc_accessor_nand;
|
||||
// Hooks
|
||||
uintptr_t sdmmc_wrapper_read;
|
||||
uintptr_t sdmmc_wrapper_write;
|
||||
uintptr_t rtld;
|
||||
uintptr_t rtld_destination;
|
||||
uintptr_t clkrst_set_min_v_clock_rate;
|
||||
// Misc funcs
|
||||
uintptr_t lock_mutex;
|
||||
uintptr_t unlock_mutex;
|
||||
// Misc data
|
||||
uintptr_t sd_mutex;
|
||||
uintptr_t nand_mutex;
|
||||
uintptr_t active_partition;
|
||||
uintptr_t sdmmc_das_handle;
|
||||
// NOPs
|
||||
uintptr_t shutdown_sd;
|
||||
uintptr_t sd_das_init;
|
||||
// Nintendo Paths
|
||||
fs_offsets_nintendo_path_t nintendo_paths[];
|
||||
} fs_offsets_t;
|
||||
|
||||
const fs_offsets_t *get_fs_offsets(enum FS_VER version);
|
||||
|
||||
#endif // __FS_OFFSETS_H__
|
55
emummc/source/FS/FS_structs.h
Normal file
55
emummc/source/FS/FS_structs.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FS_STRUCTS_H__
|
||||
#define __FS_STRUCTS_H__
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
typedef struct {
|
||||
char *device_addr_buffer;
|
||||
uint64_t device_addr_buffer_size;
|
||||
char *device_addr_buffer_masked;
|
||||
} sdmmc_dma_buffer_t;
|
||||
|
||||
_Static_assert(__alignof(sdmmc_dma_buffer_t) == 8, "sdmmc_dma_buffer_t definition");
|
||||
|
||||
typedef struct sdmmc_accessor_vt {
|
||||
void *ctor;
|
||||
void *dtor;
|
||||
void *map_device_addr_space;
|
||||
void *unmap_device_addr_space;
|
||||
void *controller_open;
|
||||
void *controller_close;
|
||||
uint64_t (*read_write)(void *, uint64_t, uint64_t, void *, uint64_t, uint64_t);
|
||||
// More not included because we don't use it.
|
||||
} sdmmc_accessor_vt_t;
|
||||
|
||||
typedef struct {
|
||||
void *vtab;
|
||||
t210_sdmmc_t *io_map;
|
||||
sdmmc_dma_buffer_t dmaBuffers[3];
|
||||
// More not included because we don't use it.
|
||||
} mmc_obj_t;
|
||||
|
||||
typedef struct {
|
||||
sdmmc_accessor_vt_t *vtab;
|
||||
mmc_obj_t *parent;
|
||||
// More not included because we don't use it.
|
||||
} sdmmc_accessor_t;
|
||||
|
||||
#endif // __FS_STRUCTS_H__
|
62
emummc/source/FS/FS_versions.h
Normal file
62
emummc/source/FS/FS_versions.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FS_VERSIONS_H__
|
||||
#define __FS_VERSIONS_H__
|
||||
|
||||
// FS Version enum
|
||||
enum FS_VER
|
||||
{
|
||||
FS_VER_1_0_0 = 0,
|
||||
|
||||
FS_VER_2_0_0,
|
||||
FS_VER_2_0_0_EXFAT,
|
||||
|
||||
FS_VER_2_1_0,
|
||||
FS_VER_2_1_0_EXFAT,
|
||||
|
||||
FS_VER_3_0_0,
|
||||
FS_VER_3_0_0_EXFAT,
|
||||
|
||||
FS_VER_3_0_1,
|
||||
FS_VER_3_0_1_EXFAT,
|
||||
|
||||
FS_VER_4_0_0,
|
||||
FS_VER_4_0_0_EXFAT,
|
||||
|
||||
FS_VER_4_1_0,
|
||||
FS_VER_4_1_0_EXFAT,
|
||||
|
||||
FS_VER_5_0_0,
|
||||
FS_VER_5_0_0_EXFAT,
|
||||
|
||||
FS_VER_5_1_0,
|
||||
FS_VER_5_1_0_EXFAT,
|
||||
|
||||
FS_VER_6_0_0,
|
||||
FS_VER_6_0_0_EXFAT,
|
||||
|
||||
FS_VER_7_0_0,
|
||||
FS_VER_7_0_0_EXFAT,
|
||||
|
||||
FS_VER_8_0_0,
|
||||
FS_VER_8_0_0_EXFAT,
|
||||
|
||||
FS_VER_MAX,
|
||||
};
|
||||
|
||||
#endif // __FS_VERSIONS_H__
|
57
emummc/source/FS/offsets/100.h
Normal file
57
emummc/source/FS/offsets/100.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_100_H__
|
||||
#define __FS_100_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_100_SDMMC_ACCESSOR_GC 0x6F850
|
||||
#define FS_OFFSET_100_SDMMC_ACCESSOR_SD 0x6F65C
|
||||
#define FS_OFFSET_100_SDMMC_ACCESSOR_NAND 0x6F230
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_100_SDMMC_WRAPPER_READ 0x6A930
|
||||
#define FS_OFFSET_100_SDMMC_WRAPPER_WRITE 0x6A9F0
|
||||
#define FS_OFFSET_100_RTLD 0x534
|
||||
#define FS_OFFSET_100_RTLD_DESTINATION 0xA0
|
||||
|
||||
#define FS_OFFSET_100_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_100_LOCK_MUTEX 0x2884
|
||||
#define FS_OFFSET_100_UNLOCK_MUTEX 0x28F0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_100_SD_MUTEX 0xE36058
|
||||
#define FS_OFFSET_100_NAND_MUTEX 0xE30610
|
||||
#define FS_OFFSET_100_ACTIVE_PARTITION 0xE30650
|
||||
#define FS_OFFSET_100_SDMMC_DAS_HANDLE 0xE2F730
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_100_SHUTDOWN_SD 0x22548
|
||||
#define FS_OFFSET_100_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_100_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 9, .adrp_offset = 0x00032C58}, \
|
||||
{.opcode_reg = 8, .adrp_offset = 0x00032C60}, \
|
||||
{.opcode_reg = 9, .adrp_offset = 0x00032F3C}, \
|
||||
{.opcode_reg = 8, .adrp_offset = 0x00032F44}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_100_H__
|
56
emummc/source/FS/offsets/200.h
Normal file
56
emummc/source/FS/offsets/200.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_200_H__
|
||||
#define __FS_200_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_200_SDMMC_ACCESSOR_GC 0x78BAC
|
||||
#define FS_OFFSET_200_SDMMC_ACCESSOR_SD 0x7894C
|
||||
#define FS_OFFSET_200_SDMMC_ACCESSOR_NAND 0x784BC
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_200_SDMMC_WRAPPER_READ 0x73478
|
||||
#define FS_OFFSET_200_SDMMC_WRAPPER_WRITE 0x73538
|
||||
#define FS_OFFSET_200_RTLD 0x500
|
||||
#define FS_OFFSET_200_RTLD_DESTINATION 0x98
|
||||
|
||||
#define FS_OFFSET_200_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_200_LOCK_MUTEX 0x3264
|
||||
#define FS_OFFSET_200_UNLOCK_MUTEX 0x32D0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_200_SD_MUTEX 0xE42268
|
||||
#define FS_OFFSET_200_NAND_MUTEX 0xE3CED0
|
||||
#define FS_OFFSET_200_ACTIVE_PARTITION 0xE3CF10
|
||||
#define FS_OFFSET_200_SDMMC_DAS_HANDLE 0xE3BDD0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_200_SHUTDOWN_SD 0x20C48
|
||||
#define FS_OFFSET_200_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_200_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00033F08}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035084}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003537C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_200_H__
|
56
emummc/source/FS/offsets/200_exfat.h
Normal file
56
emummc/source/FS/offsets/200_exfat.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_200_EXFAT_H__
|
||||
#define __FS_200_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_200_EXFAT_SDMMC_ACCESSOR_GC 0x78BAC
|
||||
#define FS_OFFSET_200_EXFAT_SDMMC_ACCESSOR_SD 0x7894C
|
||||
#define FS_OFFSET_200_EXFAT_SDMMC_ACCESSOR_NAND 0x784BC
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_200_EXFAT_SDMMC_WRAPPER_READ 0x73478
|
||||
#define FS_OFFSET_200_EXFAT_SDMMC_WRAPPER_WRITE 0x73538
|
||||
#define FS_OFFSET_200_EXFAT_RTLD 0x500
|
||||
#define FS_OFFSET_200_EXFAT_RTLD_DESTINATION 0x98
|
||||
|
||||
#define FS_OFFSET_200_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_200_EXFAT_LOCK_MUTEX 0x3264
|
||||
#define FS_OFFSET_200_EXFAT_UNLOCK_MUTEX 0x32D0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_200_EXFAT_SD_MUTEX 0xF22268
|
||||
#define FS_OFFSET_200_EXFAT_NAND_MUTEX 0xF1CED0
|
||||
#define FS_OFFSET_200_EXFAT_ACTIVE_PARTITION 0xF1CF10
|
||||
#define FS_OFFSET_200_EXFAT_SDMMC_DAS_HANDLE 0xF1BDD0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_200_EXFAT_SHUTDOWN_SD 0x20C48
|
||||
#define FS_OFFSET_200_EXFAT_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_200_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00033F08}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035084}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003537C}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_200_EXFAT_H__
|
56
emummc/source/FS/offsets/210.h
Normal file
56
emummc/source/FS/offsets/210.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_210_H__
|
||||
#define __FS_210_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_210_SDMMC_ACCESSOR_GC 0x78F8C
|
||||
#define FS_OFFSET_210_SDMMC_ACCESSOR_SD 0x78D2C
|
||||
#define FS_OFFSET_210_SDMMC_ACCESSOR_NAND 0x7889C
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_210_SDMMC_WRAPPER_READ 0x73858
|
||||
#define FS_OFFSET_210_SDMMC_WRAPPER_WRITE 0x73918
|
||||
#define FS_OFFSET_210_RTLD 0x500
|
||||
#define FS_OFFSET_210_RTLD_DESTINATION 0x98
|
||||
|
||||
#define FS_OFFSET_210_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_210_LOCK_MUTEX 0x3264
|
||||
#define FS_OFFSET_210_UNLOCK_MUTEX 0x32D0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_210_SD_MUTEX 0xE43268
|
||||
#define FS_OFFSET_210_NAND_MUTEX 0xE3DED0
|
||||
#define FS_OFFSET_210_ACTIVE_PARTITION 0xE3DF10
|
||||
#define FS_OFFSET_210_SDMMC_DAS_HANDLE 0xE3CDD0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_210_SHUTDOWN_SD 0x20E60
|
||||
#define FS_OFFSET_210_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_210_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000342E0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003545C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035754}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_210_H__
|
56
emummc/source/FS/offsets/210_exfat.h
Normal file
56
emummc/source/FS/offsets/210_exfat.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_210_EXFAT_H__
|
||||
#define __FS_210_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_210_EXFAT_SDMMC_ACCESSOR_GC 0x78F8C
|
||||
#define FS_OFFSET_210_EXFAT_SDMMC_ACCESSOR_SD 0x78D2C
|
||||
#define FS_OFFSET_210_EXFAT_SDMMC_ACCESSOR_NAND 0x7889C
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_210_EXFAT_SDMMC_WRAPPER_READ 0x73858
|
||||
#define FS_OFFSET_210_EXFAT_SDMMC_WRAPPER_WRITE 0x73918
|
||||
#define FS_OFFSET_210_EXFAT_RTLD 0x500
|
||||
#define FS_OFFSET_210_EXFAT_RTLD_DESTINATION 0x98
|
||||
|
||||
#define FS_OFFSET_210_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_210_EXFAT_LOCK_MUTEX 0x3264
|
||||
#define FS_OFFSET_210_EXFAT_UNLOCK_MUTEX 0x32D0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_210_EXFAT_SD_MUTEX 0xF22268
|
||||
#define FS_OFFSET_210_EXFAT_NAND_MUTEX 0xF1CED0
|
||||
#define FS_OFFSET_210_EXFAT_ACTIVE_PARTITION 0xF1CF10
|
||||
#define FS_OFFSET_210_EXFAT_SDMMC_DAS_HANDLE 0xF1BDD0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_210_EXFAT_SHUTDOWN_SD 0x20E60
|
||||
#define FS_OFFSET_210_EXFAT_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_210_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000342E0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003545C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00035754}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_210_EXFAT_H__
|
56
emummc/source/FS/offsets/300.h
Normal file
56
emummc/source/FS/offsets/300.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_300_H__
|
||||
#define __FS_300_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_300_SDMMC_ACCESSOR_GC 0x8FAAC
|
||||
#define FS_OFFSET_300_SDMMC_ACCESSOR_SD 0x8F84C
|
||||
#define FS_OFFSET_300_SDMMC_ACCESSOR_NAND 0x8F3B8
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_300_SDMMC_WRAPPER_READ 0x8A2F4
|
||||
#define FS_OFFSET_300_SDMMC_WRAPPER_WRITE 0x8A3B4
|
||||
#define FS_OFFSET_300_RTLD 0x4E8
|
||||
#define FS_OFFSET_300_RTLD_DESTINATION 0x8C
|
||||
|
||||
#define FS_OFFSET_300_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_300_LOCK_MUTEX 0x35CC
|
||||
#define FS_OFFSET_300_UNLOCK_MUTEX 0x3638
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_300_SD_MUTEX 0xE69268
|
||||
#define FS_OFFSET_300_NAND_MUTEX 0xE646F0
|
||||
#define FS_OFFSET_300_ACTIVE_PARTITION 0xE64730
|
||||
#define FS_OFFSET_300_SDMMC_DAS_HANDLE 0xE635A0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_300_SHUTDOWN_SD 0x258D8
|
||||
#define FS_OFFSET_300_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_300_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000391F4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A480}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A778}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_300_H__
|
56
emummc/source/FS/offsets/300_exfat.h
Normal file
56
emummc/source/FS/offsets/300_exfat.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_300_EXFAT_H__
|
||||
#define __FS_300_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_300_EXFAT_SDMMC_ACCESSOR_GC 0x8FAAC
|
||||
#define FS_OFFSET_300_EXFAT_SDMMC_ACCESSOR_SD 0x8F84C
|
||||
#define FS_OFFSET_300_EXFAT_SDMMC_ACCESSOR_NAND 0x8F3B8
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_300_EXFAT_SDMMC_WRAPPER_READ 0x8A2F4
|
||||
#define FS_OFFSET_300_EXFAT_SDMMC_WRAPPER_WRITE 0x8A3B4
|
||||
#define FS_OFFSET_300_EXFAT_RTLD 0x4E8
|
||||
#define FS_OFFSET_300_EXFAT_RTLD_DESTINATION 0x8C
|
||||
|
||||
#define FS_OFFSET_300_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_300_EXFAT_LOCK_MUTEX 0x35CC
|
||||
#define FS_OFFSET_300_EXFAT_UNLOCK_MUTEX 0x3638
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_300_EXFAT_SD_MUTEX 0xF4C268
|
||||
#define FS_OFFSET_300_EXFAT_NAND_MUTEX 0xF476F0
|
||||
#define FS_OFFSET_300_EXFAT_ACTIVE_PARTITION 0xF47730
|
||||
#define FS_OFFSET_300_EXFAT_SDMMC_DAS_HANDLE 0xF465A0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_300_EXFAT_SHUTDOWN_SD 0x258D8
|
||||
#define FS_OFFSET_300_EXFAT_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_300_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000391F4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A480}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A778}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_300_EXFAT_H__
|
56
emummc/source/FS/offsets/301.h
Normal file
56
emummc/source/FS/offsets/301.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_301_H__
|
||||
#define __FS_301_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_301_SDMMC_ACCESSOR_GC 0x8FB68
|
||||
#define FS_OFFSET_301_SDMMC_ACCESSOR_SD 0x8F908
|
||||
#define FS_OFFSET_301_SDMMC_ACCESSOR_NAND 0x8F474
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_301_SDMMC_WRAPPER_READ 0x8A3B0
|
||||
#define FS_OFFSET_301_SDMMC_WRAPPER_WRITE 0x8A470
|
||||
#define FS_OFFSET_301_RTLD 0x4E8
|
||||
#define FS_OFFSET_301_RTLD_DESTINATION 0x8C
|
||||
|
||||
#define FS_OFFSET_301_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_301_LOCK_MUTEX 0x3638
|
||||
#define FS_OFFSET_301_UNLOCK_MUTEX 0x36A4
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_301_SD_MUTEX 0xE69268
|
||||
#define FS_OFFSET_301_NAND_MUTEX 0xE646F0
|
||||
#define FS_OFFSET_301_ACTIVE_PARTITION 0xE64730
|
||||
#define FS_OFFSET_301_SDMMC_DAS_HANDLE 0xE635A0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_301_SHUTDOWN_SD 0x25944
|
||||
#define FS_OFFSET_301_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_301_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00039260}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A4EC}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A7E4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_301_H__
|
56
emummc/source/FS/offsets/301_exfat.h
Normal file
56
emummc/source/FS/offsets/301_exfat.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_301_EXFAT_H__
|
||||
#define __FS_301_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_301_EXFAT_SDMMC_ACCESSOR_GC 0x8FB68
|
||||
#define FS_OFFSET_301_EXFAT_SDMMC_ACCESSOR_SD 0x8F908
|
||||
#define FS_OFFSET_301_EXFAT_SDMMC_ACCESSOR_NAND 0x8F474
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_301_EXFAT_SDMMC_WRAPPER_READ 0x8A3B0
|
||||
#define FS_OFFSET_301_EXFAT_SDMMC_WRAPPER_WRITE 0x8A470
|
||||
#define FS_OFFSET_301_EXFAT_RTLD 0x4E8
|
||||
#define FS_OFFSET_301_EXFAT_RTLD_DESTINATION 0x8C
|
||||
|
||||
#define FS_OFFSET_301_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_301_EXFAT_LOCK_MUTEX 0x3638
|
||||
#define FS_OFFSET_301_EXFAT_UNLOCK_MUTEX 0x36A4
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_301_EXFAT_SD_MUTEX 0xF4C268
|
||||
#define FS_OFFSET_301_EXFAT_NAND_MUTEX 0xF476F0
|
||||
#define FS_OFFSET_301_EXFAT_ACTIVE_PARTITION 0xF47730
|
||||
#define FS_OFFSET_301_EXFAT_SDMMC_DAS_HANDLE 0xF465A0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_301_EXFAT_SHUTDOWN_SD 0x25944
|
||||
#define FS_OFFSET_301_EXFAT_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_301_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00039260}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A4EC}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0003A7E4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_301_EXFAT_H__
|
56
emummc/source/FS/offsets/400.h
Normal file
56
emummc/source/FS/offsets/400.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_400_H__
|
||||
#define __FS_400_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_400_SDMMC_ACCESSOR_GC 0xA3374
|
||||
#define FS_OFFSET_400_SDMMC_ACCESSOR_SD 0xA3114
|
||||
#define FS_OFFSET_400_SDMMC_ACCESSOR_NAND 0xA2C80
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_400_SDMMC_WRAPPER_READ 0x9DBCC
|
||||
#define FS_OFFSET_400_SDMMC_WRAPPER_WRITE 0x9DC8C
|
||||
#define FS_OFFSET_400_RTLD 0x4DC
|
||||
#define FS_OFFSET_400_RTLD_DESTINATION 0x98
|
||||
|
||||
#define FS_OFFSET_400_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_400_LOCK_MUTEX 0x39A0
|
||||
#define FS_OFFSET_400_UNLOCK_MUTEX 0x3A0C
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_400_SD_MUTEX 0xE80268
|
||||
#define FS_OFFSET_400_NAND_MUTEX 0xE7BC60
|
||||
#define FS_OFFSET_400_ACTIVE_PARTITION 0xE7BCA0
|
||||
#define FS_OFFSET_400_SDMMC_DAS_HANDLE 0xE7ABF0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_400_SHUTDOWN_SD 0x32D70
|
||||
#define FS_OFFSET_400_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_400_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_400_H__
|
56
emummc/source/FS/offsets/400_exfat.h
Normal file
56
emummc/source/FS/offsets/400_exfat.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_400_EXFAT_H__
|
||||
#define __FS_400_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_400_EXFAT_SDMMC_ACCESSOR_GC 0xA3374
|
||||
#define FS_OFFSET_400_EXFAT_SDMMC_ACCESSOR_SD 0xA3114
|
||||
#define FS_OFFSET_400_EXFAT_SDMMC_ACCESSOR_NAND 0xA2C80
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_400_EXFAT_SDMMC_WRAPPER_READ 0x9DBCC
|
||||
#define FS_OFFSET_400_EXFAT_SDMMC_WRAPPER_WRITE 0x9DC8C
|
||||
#define FS_OFFSET_400_EXFAT_RTLD 0x4DC
|
||||
#define FS_OFFSET_400_EXFAT_RTLD_DESTINATION 0x98
|
||||
|
||||
#define FS_OFFSET_400_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_400_EXFAT_LOCK_MUTEX 0x39A0
|
||||
#define FS_OFFSET_400_EXFAT_UNLOCK_MUTEX 0x3A0C
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_400_EXFAT_SD_MUTEX 0xF63268
|
||||
#define FS_OFFSET_400_EXFAT_NAND_MUTEX 0xF5EC60
|
||||
#define FS_OFFSET_400_EXFAT_ACTIVE_PARTITION 0xF5ECA0
|
||||
#define FS_OFFSET_400_EXFAT_SDMMC_DAS_HANDLE 0xF5DBF0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_400_EXFAT_SHUTDOWN_SD 0x32D70
|
||||
#define FS_OFFSET_400_EXFAT_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_400_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_400_EXFAT_H__
|
56
emummc/source/FS/offsets/410.h
Normal file
56
emummc/source/FS/offsets/410.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_410_H__
|
||||
#define __FS_410_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_410_SDMMC_ACCESSOR_GC 0xA33D8
|
||||
#define FS_OFFSET_410_SDMMC_ACCESSOR_SD 0xA3178
|
||||
#define FS_OFFSET_410_SDMMC_ACCESSOR_NAND 0xA2CE4
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_410_SDMMC_WRAPPER_READ 0x9DC30
|
||||
#define FS_OFFSET_410_SDMMC_WRAPPER_WRITE 0x9DCF0
|
||||
#define FS_OFFSET_410_RTLD 0x4DC
|
||||
#define FS_OFFSET_410_RTLD_DESTINATION 0x98
|
||||
|
||||
#define FS_OFFSET_410_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_410_LOCK_MUTEX 0x39A0
|
||||
#define FS_OFFSET_410_UNLOCK_MUTEX 0x3A0C
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_410_SD_MUTEX 0xE80268
|
||||
#define FS_OFFSET_410_NAND_MUTEX 0xE7BC60
|
||||
#define FS_OFFSET_410_ACTIVE_PARTITION 0xE7BCA0
|
||||
#define FS_OFFSET_410_SDMMC_DAS_HANDLE 0xE7ABF0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_410_SHUTDOWN_SD 0x32D70
|
||||
#define FS_OFFSET_410_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_410_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_410_H__
|
56
emummc/source/FS/offsets/410_exfat.h
Normal file
56
emummc/source/FS/offsets/410_exfat.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_410_EXFAT_H__
|
||||
#define __FS_410_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_410_EXFAT_SDMMC_ACCESSOR_GC 0xA33D8
|
||||
#define FS_OFFSET_410_EXFAT_SDMMC_ACCESSOR_SD 0xA3178
|
||||
#define FS_OFFSET_410_EXFAT_SDMMC_ACCESSOR_NAND 0xA2CE4
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_410_EXFAT_SDMMC_WRAPPER_READ 0x9DC30
|
||||
#define FS_OFFSET_410_EXFAT_SDMMC_WRAPPER_WRITE 0x9DCF0
|
||||
#define FS_OFFSET_410_EXFAT_RTLD 0x4DC
|
||||
#define FS_OFFSET_410_EXFAT_RTLD_DESTINATION 0x98
|
||||
|
||||
#define FS_OFFSET_410_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_410_EXFAT_LOCK_MUTEX 0x39A0
|
||||
#define FS_OFFSET_410_EXFAT_UNLOCK_MUTEX 0x3A0C
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_410_EXFAT_SD_MUTEX 0xF63268
|
||||
#define FS_OFFSET_410_EXFAT_NAND_MUTEX 0xF5EC60
|
||||
#define FS_OFFSET_410_EXFAT_ACTIVE_PARTITION 0xF5ECA0
|
||||
#define FS_OFFSET_410_EXFAT_SDMMC_DAS_HANDLE 0xF5DBF0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_410_EXFAT_SHUTDOWN_SD 0x32D70
|
||||
#define FS_OFFSET_410_EXFAT_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_410_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002023C}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021BE8}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00021EC4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_410_EXFAT_H__
|
56
emummc/source/FS/offsets/500.h
Normal file
56
emummc/source/FS/offsets/500.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_500_H__
|
||||
#define __FS_500_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_500_SDMMC_ACCESSOR_GC 0xCF250
|
||||
#define FS_OFFSET_500_SDMMC_ACCESSOR_SD 0xCEFD0
|
||||
#define FS_OFFSET_500_SDMMC_ACCESSOR_NAND 0xCE990
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_500_SDMMC_WRAPPER_READ 0xC9420
|
||||
#define FS_OFFSET_500_SDMMC_WRAPPER_WRITE 0xC9500
|
||||
#define FS_OFFSET_500_RTLD 0x584
|
||||
#define FS_OFFSET_500_RTLD_DESTINATION 0x94
|
||||
|
||||
#define FS_OFFSET_500_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_500_LOCK_MUTEX 0x4080
|
||||
#define FS_OFFSET_500_UNLOCK_MUTEX 0x40D0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_500_SD_MUTEX 0xEC3268
|
||||
#define FS_OFFSET_500_NAND_MUTEX 0xEBDE58
|
||||
#define FS_OFFSET_500_ACTIVE_PARTITION 0xEBDE98
|
||||
#define FS_OFFSET_500_SDMMC_DAS_HANDLE 0xEBCE30
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_500_SHUTDOWN_SD 0x443E8
|
||||
#define FS_OFFSET_500_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_500_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00028980}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002ACE4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B220}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_500_H__
|
56
emummc/source/FS/offsets/500_exfat.h
Normal file
56
emummc/source/FS/offsets/500_exfat.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_500_EXFAT_H__
|
||||
#define __FS_500_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_500_EXFAT_SDMMC_ACCESSOR_GC 0xCF250
|
||||
#define FS_OFFSET_500_EXFAT_SDMMC_ACCESSOR_SD 0xCEFD0
|
||||
#define FS_OFFSET_500_EXFAT_SDMMC_ACCESSOR_NAND 0xCE990
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_500_EXFAT_SDMMC_WRAPPER_READ 0xC9420
|
||||
#define FS_OFFSET_500_EXFAT_SDMMC_WRAPPER_WRITE 0xC9500
|
||||
#define FS_OFFSET_500_EXFAT_RTLD 0x584
|
||||
#define FS_OFFSET_500_EXFAT_RTLD_DESTINATION 0x94
|
||||
|
||||
#define FS_OFFSET_500_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_500_EXFAT_LOCK_MUTEX 0x4080
|
||||
#define FS_OFFSET_500_EXFAT_UNLOCK_MUTEX 0x40D0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_500_EXFAT_SD_MUTEX 0xFA8268
|
||||
#define FS_OFFSET_500_EXFAT_NAND_MUTEX 0xFA2E58
|
||||
#define FS_OFFSET_500_EXFAT_ACTIVE_PARTITION 0xFA2E98
|
||||
#define FS_OFFSET_500_EXFAT_SDMMC_DAS_HANDLE 0xFA1E30
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_500_EXFAT_SHUTDOWN_SD 0x443E8
|
||||
#define FS_OFFSET_500_EXFAT_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_500_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00028980}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002ACE4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B220}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_500_EXFAT_H__
|
56
emummc/source/FS/offsets/510.h
Normal file
56
emummc/source/FS/offsets/510.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_510_H__
|
||||
#define __FS_510_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_510_SDMMC_ACCESSOR_GC 0xCF620
|
||||
#define FS_OFFSET_510_SDMMC_ACCESSOR_SD 0xCF3A0
|
||||
#define FS_OFFSET_510_SDMMC_ACCESSOR_NAND 0xCED60
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_510_SDMMC_WRAPPER_READ 0xC97F0
|
||||
#define FS_OFFSET_510_SDMMC_WRAPPER_WRITE 0xC98D0
|
||||
#define FS_OFFSET_510_RTLD 0x584
|
||||
#define FS_OFFSET_510_RTLD_DESTINATION 0x94
|
||||
|
||||
#define FS_OFFSET_510_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_510_LOCK_MUTEX 0x4080
|
||||
#define FS_OFFSET_510_UNLOCK_MUTEX 0x40D0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_510_SD_MUTEX 0xEC4268
|
||||
#define FS_OFFSET_510_NAND_MUTEX 0xEBEE58
|
||||
#define FS_OFFSET_510_ACTIVE_PARTITION 0xEBEE98
|
||||
#define FS_OFFSET_510_SDMMC_DAS_HANDLE 0xEBDE30
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_510_SHUTDOWN_SD 0x44578
|
||||
#define FS_OFFSET_510_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_510_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000289B0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002AD14}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B250}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_510_H__
|
56
emummc/source/FS/offsets/510_exfat.h
Normal file
56
emummc/source/FS/offsets/510_exfat.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_510_EXFAT_H__
|
||||
#define __FS_510_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_510_EXFAT_SDMMC_ACCESSOR_GC 0xCF620
|
||||
#define FS_OFFSET_510_EXFAT_SDMMC_ACCESSOR_SD 0xCF3A0
|
||||
#define FS_OFFSET_510_EXFAT_SDMMC_ACCESSOR_NAND 0xCED60
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_510_EXFAT_SDMMC_WRAPPER_READ 0xC97F0
|
||||
#define FS_OFFSET_510_EXFAT_SDMMC_WRAPPER_WRITE 0xC98D0
|
||||
#define FS_OFFSET_510_EXFAT_RTLD 0x584
|
||||
#define FS_OFFSET_510_EXFAT_RTLD_DESTINATION 0x94
|
||||
|
||||
#define FS_OFFSET_510_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_510_EXFAT_LOCK_MUTEX 0x4080
|
||||
#define FS_OFFSET_510_EXFAT_UNLOCK_MUTEX 0x40D0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_510_EXFAT_SD_MUTEX 0xFA9268
|
||||
#define FS_OFFSET_510_EXFAT_NAND_MUTEX 0xFA3E58
|
||||
#define FS_OFFSET_510_EXFAT_ACTIVE_PARTITION 0xFA3E98
|
||||
#define FS_OFFSET_510_EXFAT_SDMMC_DAS_HANDLE 0xFA2E30
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_510_EXFAT_SHUTDOWN_SD 0x44578
|
||||
#define FS_OFFSET_510_EXFAT_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_510_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000289B0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002AD14}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0002B250}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_510_EXFAT_H__
|
57
emummc/source/FS/offsets/600.h
Normal file
57
emummc/source/FS/offsets/600.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_600_H__
|
||||
#define __FS_600_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_600_SDMMC_ACCESSOR_GC 0x153780
|
||||
#define FS_OFFSET_600_SDMMC_ACCESSOR_SD 0x1534F0
|
||||
#define FS_OFFSET_600_SDMMC_ACCESSOR_NAND 0x14F990
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_600_SDMMC_WRAPPER_READ 0x1485A0
|
||||
#define FS_OFFSET_600_SDMMC_WRAPPER_WRITE 0x148680
|
||||
#define FS_OFFSET_600_RTLD 0x5B0
|
||||
#define FS_OFFSET_600_RTLD_DESTINATION 0x98
|
||||
|
||||
#define FS_OFFSET_600_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_600_LOCK_MUTEX 0x1412C0
|
||||
#define FS_OFFSET_600_UNLOCK_MUTEX 0x141310
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_600_SD_MUTEX 0xF06268
|
||||
#define FS_OFFSET_600_NAND_MUTEX 0xF01BA0
|
||||
#define FS_OFFSET_600_ACTIVE_PARTITION 0xF01BE0
|
||||
#define FS_OFFSET_600_SDMMC_DAS_HANDLE 0xE01670
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_600_SHUTDOWN_SD 0xB2F28
|
||||
#define FS_OFFSET_600_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_600_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000790DC}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007A924}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007AB18}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007AEF4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0} \
|
||||
}
|
||||
|
||||
#endif // __FS_600_H__
|
57
emummc/source/FS/offsets/600_exfat.h
Normal file
57
emummc/source/FS/offsets/600_exfat.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_600_EXFAT_H__
|
||||
#define __FS_600_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_600_EXFAT_SDMMC_ACCESSOR_GC 0x15EE80
|
||||
#define FS_OFFSET_600_EXFAT_SDMMC_ACCESSOR_SD 0x15EBF0
|
||||
#define FS_OFFSET_600_EXFAT_SDMMC_ACCESSOR_NAND 0x15B090
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_600_EXFAT_SDMMC_WRAPPER_READ 0x153CA0
|
||||
#define FS_OFFSET_600_EXFAT_SDMMC_WRAPPER_WRITE 0x153D80
|
||||
#define FS_OFFSET_600_EXFAT_RTLD 0x5B0
|
||||
#define FS_OFFSET_600_EXFAT_RTLD_DESTINATION 0x98
|
||||
|
||||
#define FS_OFFSET_600_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_600_EXFAT_LOCK_MUTEX 0x14C9C0
|
||||
#define FS_OFFSET_600_EXFAT_UNLOCK_MUTEX 0x14CA10
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_600_EXFAT_SD_MUTEX 0xFEB268
|
||||
#define FS_OFFSET_600_EXFAT_NAND_MUTEX 0xFE6BA0
|
||||
#define FS_OFFSET_600_EXFAT_ACTIVE_PARTITION 0xFE6BE0
|
||||
#define FS_OFFSET_600_EXFAT_SDMMC_DAS_HANDLE 0xEE6670
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_600_EXFAT_SHUTDOWN_SD 0xBE628
|
||||
#define FS_OFFSET_600_EXFAT_SD_DAS_INIT 0x0
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_600_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000847DC}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00086024}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00086218}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000865F4}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0} \
|
||||
}
|
||||
|
||||
#endif // __FS_600_EXFAT_H__
|
58
emummc/source/FS/offsets/700.h
Normal file
58
emummc/source/FS/offsets/700.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_700_H__
|
||||
#define __FS_700_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_700_SDMMC_ACCESSOR_GC 0x15BD90
|
||||
#define FS_OFFSET_700_SDMMC_ACCESSOR_SD 0x15BB00
|
||||
#define FS_OFFSET_700_SDMMC_ACCESSOR_NAND 0x157FF0
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_700_SDMMC_WRAPPER_READ 0x14FDF0
|
||||
#define FS_OFFSET_700_SDMMC_WRAPPER_WRITE 0x14FED0
|
||||
#define FS_OFFSET_700_RTLD 0x5B4
|
||||
#define FS_OFFSET_700_RTLD_DESTINATION 0x9C
|
||||
|
||||
#define FS_OFFSET_700_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_700_LOCK_MUTEX 0x148A90
|
||||
#define FS_OFFSET_700_UNLOCK_MUTEX 0x148AE0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_700_SD_MUTEX 0xF123E8
|
||||
#define FS_OFFSET_700_NAND_MUTEX 0xF0DBE8
|
||||
#define FS_OFFSET_700_ACTIVE_PARTITION 0xF0DC28
|
||||
#define FS_OFFSET_700_SDMMC_DAS_HANDLE 0xE0E7A0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_700_SHUTDOWN_SD 0xB8FCC
|
||||
#define FS_OFFSET_700_SD_DAS_INIT 0x85FE8
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_700_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007DA90}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F344}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F538}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F914}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0007FAD8}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_700_H__
|
58
emummc/source/FS/offsets/700_exfat.h
Normal file
58
emummc/source/FS/offsets/700_exfat.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_700_EXFAT_H__
|
||||
#define __FS_700_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_700_EXFAT_SDMMC_ACCESSOR_GC 0x167340
|
||||
#define FS_OFFSET_700_EXFAT_SDMMC_ACCESSOR_SD 0x1670B0
|
||||
#define FS_OFFSET_700_EXFAT_SDMMC_ACCESSOR_NAND 0x1635A0
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_700_EXFAT_SDMMC_WRAPPER_READ 0x15B3A0
|
||||
#define FS_OFFSET_700_EXFAT_SDMMC_WRAPPER_WRITE 0x15B480
|
||||
#define FS_OFFSET_700_EXFAT_RTLD 0x5B4
|
||||
#define FS_OFFSET_700_EXFAT_RTLD_DESTINATION 0x9C
|
||||
|
||||
#define FS_OFFSET_700_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_700_EXFAT_LOCK_MUTEX 0x154040
|
||||
#define FS_OFFSET_700_EXFAT_UNLOCK_MUTEX 0x154090
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_700_EXFAT_SD_MUTEX 0xFF73E8
|
||||
#define FS_OFFSET_700_EXFAT_NAND_MUTEX 0xFF2BE8
|
||||
#define FS_OFFSET_700_EXFAT_ACTIVE_PARTITION 0xFF2C28
|
||||
#define FS_OFFSET_700_EXFAT_SDMMC_DAS_HANDLE 0xEF3A00
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_700_EXFAT_SHUTDOWN_SD 0xC457C
|
||||
#define FS_OFFSET_700_EXFAT_SD_DAS_INIT 0x91598
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_700_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00089040}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008A8F4}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008AAE8}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008AEC4}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0008B088}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_700_EXFAT_H__
|
58
emummc/source/FS/offsets/800.h
Normal file
58
emummc/source/FS/offsets/800.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_800_H__
|
||||
#define __FS_800_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_800_SDMMC_ACCESSOR_GC 0x15EA20
|
||||
#define FS_OFFSET_800_SDMMC_ACCESSOR_SD 0x15E790
|
||||
#define FS_OFFSET_800_SDMMC_ACCESSOR_NAND 0x15AC80
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_800_SDMMC_WRAPPER_READ 0x152A80
|
||||
#define FS_OFFSET_800_SDMMC_WRAPPER_WRITE 0x152B60
|
||||
#define FS_OFFSET_800_RTLD 0x5B4
|
||||
#define FS_OFFSET_800_RTLD_DESTINATION 0x9C
|
||||
|
||||
#define FS_OFFSET_800_CLKRST_SET_MIN_V_CLK_RATE 0x16F370
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_800_LOCK_MUTEX 0x14B6D0
|
||||
#define FS_OFFSET_800_UNLOCK_MUTEX 0x14B720
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_800_SD_MUTEX 0xF1A3E8
|
||||
#define FS_OFFSET_800_NAND_MUTEX 0xF15BE8
|
||||
#define FS_OFFSET_800_ACTIVE_PARTITION 0xF15C28
|
||||
#define FS_OFFSET_800_SDMMC_DAS_HANDLE 0xE167C0
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_800_SHUTDOWN_SD 0xBAF6C
|
||||
#define FS_OFFSET_800_SD_DAS_INIT 0x87D58
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_800_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0007F5F0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081084}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081278}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00081654}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x00081818}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0} \
|
||||
}
|
||||
|
||||
#endif // __FS_800_H__
|
58
emummc/source/FS/offsets/800_exfat.h
Normal file
58
emummc/source/FS/offsets/800_exfat.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_800_EXFAT_H__
|
||||
#define __FS_800_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_800_EXFAT_SDMMC_ACCESSOR_GC 0x169FD0
|
||||
#define FS_OFFSET_800_EXFAT_SDMMC_ACCESSOR_SD 0x169D40
|
||||
#define FS_OFFSET_800_EXFAT_SDMMC_ACCESSOR_NAND 0x166230
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_800_EXFAT_SDMMC_WRAPPER_READ 0x15E030
|
||||
#define FS_OFFSET_800_EXFAT_SDMMC_WRAPPER_WRITE 0x15E110
|
||||
#define FS_OFFSET_800_EXFAT_RTLD 0x5B4
|
||||
#define FS_OFFSET_800_EXFAT_RTLD_DESTINATION 0x9C
|
||||
|
||||
#define FS_OFFSET_800_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x17A920
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_800_EXFAT_LOCK_MUTEX 0x156C80
|
||||
#define FS_OFFSET_800_EXFAT_UNLOCK_MUTEX 0x156CD0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_800_EXFAT_SD_MUTEX 0xFFE3E8
|
||||
#define FS_OFFSET_800_EXFAT_NAND_MUTEX 0xFF9BE8
|
||||
#define FS_OFFSET_800_EXFAT_ACTIVE_PARTITION 0xFF9C28
|
||||
#define FS_OFFSET_800_EXFAT_SDMMC_DAS_HANDLE 0xEFAA20
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_800_EXFAT_SHUTDOWN_SD 0xC651C
|
||||
#define FS_OFFSET_800_EXFAT_SD_DAS_INIT 0x93308
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_800_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008ABA0}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008C634}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008C828}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x0008CC04}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0008CDC8}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0} \
|
||||
}
|
||||
|
||||
#endif // __FS_800_EXFAT_H__
|
432
emummc/source/emmc/mmc.h
Normal file
432
emummc/source/emmc/mmc.h
Normal file
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* Header for MultiMediaCard (MMC)
|
||||
*
|
||||
* Copyright 2002 Hewlett-Packard Company
|
||||
*
|
||||
* Use consistent with the GNU GPL is permitted,
|
||||
* provided that this copyright notice is
|
||||
* preserved in its entirety in all copies and derived works.
|
||||
*
|
||||
* HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
|
||||
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
|
||||
* FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*
|
||||
* Many thanks to Alessandro Rubini and Jonathan Corbet!
|
||||
*
|
||||
* Based strongly on code by:
|
||||
*
|
||||
* Author: Yong-iL Joh <tolkien@mizi.com>
|
||||
*
|
||||
* Author: Andrew Christian
|
||||
* 15 May 2002
|
||||
*/
|
||||
|
||||
#ifndef LINUX_MMC_MMC_H
|
||||
#define LINUX_MMC_MMC_H
|
||||
|
||||
/* Standard MMC commands (4.1) type argument response */
|
||||
/* class 1 */
|
||||
#define MMC_GO_IDLE_STATE 0 /* bc */
|
||||
#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
|
||||
#define MMC_ALL_SEND_CID 2 /* bcr R2 */
|
||||
#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
|
||||
#define MMC_SET_DSR 4 /* bc [31:16] RCA */
|
||||
#define MMC_SLEEP_AWAKE 5 /* ac [31:16] RCA 15:flg R1b */
|
||||
#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
|
||||
#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
|
||||
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
|
||||
#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
|
||||
#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
|
||||
#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
|
||||
#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
|
||||
#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
|
||||
#define MMC_BUS_TEST_R 14 /* adtc R1 */
|
||||
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
|
||||
#define MMC_BUS_TEST_W 19 /* adtc R1 */
|
||||
#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */
|
||||
#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
|
||||
|
||||
/* class 2 */
|
||||
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
|
||||
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
|
||||
#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
|
||||
|
||||
/* class 3 */
|
||||
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
|
||||
|
||||
/* class 4 */
|
||||
#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
|
||||
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
|
||||
#define MMC_PROGRAM_CID 26 /* adtc R1 */
|
||||
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
|
||||
|
||||
/* class 6 */
|
||||
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
|
||||
#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
|
||||
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
|
||||
|
||||
/* class 5 */
|
||||
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
|
||||
#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
|
||||
#define MMC_ERASE 38 /* ac R1b */
|
||||
|
||||
/* class 9 */
|
||||
#define MMC_FAST_IO 39 /* ac <Complex> R4 */
|
||||
#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
|
||||
|
||||
/* class 7 */
|
||||
#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
|
||||
|
||||
/* class 8 */
|
||||
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
|
||||
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
|
||||
|
||||
/* class 11 */
|
||||
#define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */
|
||||
#define MMC_QUE_TASK_ADDR 45 /* ac [31:0] data addr R1 */
|
||||
#define MMC_EXECUTE_READ_TASK 46 /* adtc [20:16] task id R1 */
|
||||
#define MMC_EXECUTE_WRITE_TASK 47 /* adtc [20:16] task id R1 */
|
||||
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
|
||||
|
||||
/*
|
||||
* MMC_SWITCH argument format:
|
||||
*
|
||||
* [31:26] Always 0
|
||||
* [25:24] Access Mode
|
||||
* [23:16] Location of target Byte in EXT_CSD
|
||||
* [15:08] Value Byte
|
||||
* [07:03] Always 0
|
||||
* [02:00] Command Set
|
||||
*/
|
||||
|
||||
/*
|
||||
MMC status in R1, for native mode (SPI bits are different)
|
||||
Type
|
||||
e : error bit
|
||||
s : status bit
|
||||
r : detected and set for the actual command response
|
||||
x : detected and set during command execution. the host must poll
|
||||
the card by sending status command in order to read these bits.
|
||||
Clear condition
|
||||
a : according to the card state
|
||||
b : always related to the previous command. Reception of
|
||||
a valid command will clear it (with a delay of one command)
|
||||
c : clear by read
|
||||
*/
|
||||
|
||||
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
|
||||
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
|
||||
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
|
||||
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
|
||||
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
|
||||
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
|
||||
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
|
||||
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
|
||||
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
|
||||
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
|
||||
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
|
||||
#define R1_CC_ERROR (1 << 20) /* erx, c */
|
||||
#define R1_ERROR (1 << 19) /* erx, c */
|
||||
#define R1_UNDERRUN (1 << 18) /* ex, c */
|
||||
#define R1_OVERRUN (1 << 17) /* ex, c */
|
||||
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
|
||||
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
|
||||
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
|
||||
#define R1_ERASE_RESET (1 << 13) /* sr, c */
|
||||
#define R1_STATUS(x) (x & 0xFFFFE000)
|
||||
#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
|
||||
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
|
||||
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
|
||||
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */
|
||||
#define R1_APP_CMD (1 << 5) /* sr, c */
|
||||
|
||||
#define R1_STATE_IDLE 0
|
||||
#define R1_STATE_READY 1
|
||||
#define R1_STATE_IDENT 2
|
||||
#define R1_STATE_STBY 3
|
||||
#define R1_STATE_TRAN 4
|
||||
#define R1_STATE_DATA 5
|
||||
#define R1_STATE_RCV 6
|
||||
#define R1_STATE_PRG 7
|
||||
#define R1_STATE_DIS 8
|
||||
|
||||
/*
|
||||
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
|
||||
* R1 is the low order byte; R2 is the next highest byte, when present.
|
||||
*/
|
||||
#define R1_SPI_IDLE (1 << 0)
|
||||
#define R1_SPI_ERASE_RESET (1 << 1)
|
||||
#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
|
||||
#define R1_SPI_COM_CRC (1 << 3)
|
||||
#define R1_SPI_ERASE_SEQ (1 << 4)
|
||||
#define R1_SPI_ADDRESS (1 << 5)
|
||||
#define R1_SPI_PARAMETER (1 << 6)
|
||||
/* R1 bit 7 is always zero */
|
||||
#define R2_SPI_CARD_LOCKED (1 << 8)
|
||||
#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */
|
||||
#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP
|
||||
#define R2_SPI_ERROR (1 << 10)
|
||||
#define R2_SPI_CC_ERROR (1 << 11)
|
||||
#define R2_SPI_CARD_ECC_ERROR (1 << 12)
|
||||
#define R2_SPI_WP_VIOLATION (1 << 13)
|
||||
#define R2_SPI_ERASE_PARAM (1 << 14)
|
||||
#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */
|
||||
#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE
|
||||
|
||||
/*
|
||||
* OCR bits are mostly in host.h
|
||||
*/
|
||||
#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
|
||||
|
||||
/*
|
||||
* Card Command Classes (CCC)
|
||||
*/
|
||||
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
|
||||
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
|
||||
/* (and for SPI, CMD58,59) */
|
||||
#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
|
||||
/* (CMD11) */
|
||||
#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
|
||||
/* (CMD16,17,18) */
|
||||
#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
|
||||
/* (CMD20) */
|
||||
#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
|
||||
/* (CMD16,24,25,26,27) */
|
||||
#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
|
||||
/* (CMD32,33,34,35,36,37,38,39) */
|
||||
#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
|
||||
/* (CMD28,29,30) */
|
||||
#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
|
||||
/* (CMD16,CMD42) */
|
||||
#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
|
||||
/* (CMD55,56,57,ACMD*) */
|
||||
#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
|
||||
/* (CMD5,39,40,52,53) */
|
||||
#define CCC_SWITCH (1<<10) /* (10) High speed switch */
|
||||
/* (CMD6,34,35,36,37,50) */
|
||||
/* (11) Reserved */
|
||||
/* (CMD?) */
|
||||
|
||||
/*
|
||||
* CSD field definitions
|
||||
*/
|
||||
|
||||
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
|
||||
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
|
||||
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
|
||||
#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
|
||||
|
||||
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
|
||||
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
|
||||
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
|
||||
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
|
||||
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
|
||||
|
||||
/*
|
||||
* EXT_CSD fields
|
||||
*/
|
||||
|
||||
#define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */
|
||||
#define EXT_CSD_FLUSH_CACHE 32 /* W */
|
||||
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
|
||||
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
|
||||
#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */
|
||||
#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */
|
||||
#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */
|
||||
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
|
||||
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
|
||||
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
|
||||
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
|
||||
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
|
||||
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
|
||||
#define EXT_CSD_HPI_MGMT 161 /* R/W */
|
||||
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
|
||||
#define EXT_CSD_BKOPS_EN 163 /* R/W */
|
||||
#define EXT_CSD_BKOPS_START 164 /* W */
|
||||
#define EXT_CSD_SANITIZE_START 165 /* W */
|
||||
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
|
||||
#define EXT_CSD_RPMB_MULT 168 /* RO */
|
||||
#define EXT_CSD_FW_CONFIG 169 /* R/W */
|
||||
#define EXT_CSD_BOOT_WP 173 /* R/W */
|
||||
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
|
||||
#define EXT_CSD_PART_CONFIG 179 /* R/W */
|
||||
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
|
||||
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
|
||||
#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
|
||||
#define EXT_CSD_HS_TIMING 185 /* R/W */
|
||||
#define EXT_CSD_POWER_CLASS 187 /* R/W */
|
||||
#define EXT_CSD_REV 192 /* RO */
|
||||
#define EXT_CSD_STRUCTURE 194 /* RO */
|
||||
#define EXT_CSD_CARD_TYPE 196 /* RO */
|
||||
#define EXT_CSD_DRIVER_STRENGTH 197 /* RO */
|
||||
#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
|
||||
#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */
|
||||
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
|
||||
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
|
||||
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
|
||||
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
|
||||
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
|
||||
#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
|
||||
#define EXT_CSD_REL_WR_SEC_C 222 /* RO */
|
||||
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
|
||||
#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
|
||||
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
|
||||
#define EXT_CSD_BOOT_MULT 226 /* RO */
|
||||
#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
|
||||
#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
|
||||
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
|
||||
#define EXT_CSD_TRIM_MULT 232 /* RO */
|
||||
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
|
||||
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
|
||||
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
|
||||
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
|
||||
#define EXT_CSD_BKOPS_STATUS 246 /* RO */
|
||||
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
|
||||
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
|
||||
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
|
||||
#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
|
||||
#define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */
|
||||
#define EXT_CSD_DEVICE_VERSION 262 /* RO, 2 bytes */
|
||||
#define EXT_CSD_PRE_EOL_INFO 267 /* RO */
|
||||
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */
|
||||
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */
|
||||
#define EXT_CSD_CMDQ_DEPTH 307 /* RO */
|
||||
#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */
|
||||
#define EXT_CSD_SUPPORTED_MODE 493 /* RO */
|
||||
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
|
||||
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
|
||||
#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
|
||||
#define EXT_CSD_MAX_PACKED_READS 501 /* RO */
|
||||
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
|
||||
#define EXT_CSD_HPI_FEATURES 503 /* RO */
|
||||
|
||||
/*
|
||||
* EXT_CSD field definitions
|
||||
*/
|
||||
|
||||
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
|
||||
|
||||
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
|
||||
#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
|
||||
#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
|
||||
#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
|
||||
|
||||
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
|
||||
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
|
||||
|
||||
#define EXT_CSD_PART_SETTING_COMPLETED (0x1)
|
||||
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
|
||||
|
||||
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
|
||||
#define EXT_CSD_CMD_SET_SECURE (1<<1)
|
||||
#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
|
||||
|
||||
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \
|
||||
EXT_CSD_CARD_TYPE_HS_52)
|
||||
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
|
||||
/* DDR mode @1.8V or 3V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
|
||||
/* DDR mode @1.2V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
|
||||
| EXT_CSD_CARD_TYPE_DDR_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */
|
||||
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */
|
||||
/* SDR mode @1.2V I/O */
|
||||
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
|
||||
EXT_CSD_CARD_TYPE_HS200_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
|
||||
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
|
||||
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
|
||||
EXT_CSD_CARD_TYPE_HS400_1_2V)
|
||||
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */
|
||||
|
||||
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
|
||||
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
|
||||
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
|
||||
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
|
||||
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
|
||||
#define EXT_CSD_BUS_WIDTH_STROBE (1<<7) /* Enhanced strobe mode */
|
||||
|
||||
#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
|
||||
#define EXT_CSD_TIMING_HS 1 /* High speed */
|
||||
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
|
||||
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
|
||||
#define EXT_CSD_DRV_STR_SHIFT 4 /* Driver Strength shift */
|
||||
|
||||
#define EXT_CSD_SEC_ER_EN (1<<0)
|
||||
#define EXT_CSD_SEC_BD_BLK_EN (1<<2)
|
||||
#define EXT_CSD_SEC_GB_CL_EN (1<<4)
|
||||
#define EXT_CSD_SEC_SANITIZE (1<<6) /* v4.5 only */
|
||||
|
||||
#define EXT_CSD_RST_N_EN_MASK 0x3
|
||||
#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
|
||||
|
||||
#define EXT_CSD_NO_POWER_NOTIFICATION 0
|
||||
#define EXT_CSD_POWER_ON 1
|
||||
#define EXT_CSD_POWER_OFF_SHORT 2
|
||||
#define EXT_CSD_POWER_OFF_LONG 3
|
||||
|
||||
#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */
|
||||
#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */
|
||||
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
|
||||
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
|
||||
|
||||
#define EXT_CSD_PACKED_EVENT_EN (1<<3)
|
||||
|
||||
/*
|
||||
* EXCEPTION_EVENT_STATUS field
|
||||
*/
|
||||
#define EXT_CSD_URGENT_BKOPS (1<<0)
|
||||
#define EXT_CSD_DYNCAP_NEEDED (1<<1)
|
||||
#define EXT_CSD_SYSPOOL_EXHAUSTED (1<<2)
|
||||
#define EXT_CSD_PACKED_FAILURE (1<<3)
|
||||
|
||||
#define EXT_CSD_PACKED_GENERIC_ERROR (1<<0)
|
||||
#define EXT_CSD_PACKED_INDEXED_ERROR (1<<1)
|
||||
|
||||
/*
|
||||
* BKOPS status level
|
||||
*/
|
||||
#define EXT_CSD_BKOPS_LEVEL_2 0x2
|
||||
|
||||
/*
|
||||
* BKOPS modes
|
||||
*/
|
||||
#define EXT_CSD_MANUAL_BKOPS_MASK 0x01
|
||||
#define EXT_CSD_AUTO_BKOPS_MASK 0x02
|
||||
|
||||
/*
|
||||
* Command Queue
|
||||
*/
|
||||
#define EXT_CSD_CMDQ_MODE_ENABLED (1<<0)
|
||||
#define EXT_CSD_CMDQ_DEPTH_MASK 0x1F
|
||||
#define EXT_CSD_CMDQ_SUPPORTED (1<<0)
|
||||
|
||||
/*
|
||||
* MMC_SWITCH access modes
|
||||
*/
|
||||
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
|
||||
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
|
||||
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
|
||||
|
||||
/*
|
||||
* Erase/trim/discard
|
||||
*/
|
||||
#define MMC_ERASE_ARG 0x00000000
|
||||
#define MMC_SECURE_ERASE_ARG 0x80000000
|
||||
#define MMC_TRIM_ARG 0x00000001
|
||||
#define MMC_DISCARD_ARG 0x00000003
|
||||
#define MMC_SECURE_TRIM1_ARG 0x80000001
|
||||
#define MMC_SECURE_TRIM2_ARG 0x80008000
|
||||
#define MMC_SECURE_ARGS 0x80000000
|
||||
#define MMC_TRIM_ARGS 0x00008001
|
||||
|
||||
#endif /* LINUX_MMC_MMC_H */
|
35
emummc/source/emmc/nx_emmc.c
Normal file
35
emummc/source/emmc/nx_emmc.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "../utils/types.h"
|
||||
#include "nx_emmc.h"
|
||||
|
||||
int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf)
|
||||
{
|
||||
// The last LBA is inclusive.
|
||||
if (part->lba_start + sector_off > part->lba_end)
|
||||
return 0;
|
||||
return sdmmc_storage_read(storage, part->lba_start + sector_off, num_sectors, buf);
|
||||
}
|
||||
|
||||
int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf)
|
||||
{
|
||||
// The last LBA is inclusive.
|
||||
if (part->lba_start + sector_off > part->lba_end)
|
||||
return 0;
|
||||
return sdmmc_storage_write(storage, part->lba_start + sector_off, num_sectors, buf);
|
||||
}
|
67
emummc/source/emmc/nx_emmc.h
Normal file
67
emummc/source/emmc/nx_emmc.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _NX_EMMC_H_
|
||||
#define _NX_EMMC_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "sdmmc.h"
|
||||
|
||||
typedef struct _gpt_entry_t
|
||||
{
|
||||
u8 type_guid[0x10];
|
||||
u8 part_guid[0x10];
|
||||
u64 lba_start;
|
||||
u64 lba_end;
|
||||
u64 attrs;
|
||||
u16 name[36];
|
||||
} gpt_entry_t;
|
||||
|
||||
typedef struct _gpt_header_t
|
||||
{
|
||||
u64 signature;
|
||||
u32 revision;
|
||||
u32 size;
|
||||
u32 crc32;
|
||||
u32 res1;
|
||||
u64 my_lba;
|
||||
u64 alt_lba;
|
||||
u64 first_use_lba;
|
||||
u64 last_use_lba;
|
||||
u8 disk_guid[0x10];
|
||||
u64 part_ent_lba;
|
||||
u32 num_part_ents;
|
||||
u32 part_ent_size;
|
||||
u32 part_ents_crc32;
|
||||
u8 res2[420];
|
||||
} gpt_header_t;
|
||||
|
||||
#define NX_GPT_FIRST_LBA 1
|
||||
#define NX_GPT_NUM_BLOCKS 33
|
||||
#define NX_EMMC_BLOCKSIZE 512
|
||||
|
||||
typedef struct _emmc_part_t
|
||||
{
|
||||
u32 lba_start;
|
||||
u32 lba_end;
|
||||
u64 attrs;
|
||||
s8 name[37];
|
||||
} emmc_part_t;
|
||||
|
||||
int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
|
||||
int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
|
||||
|
||||
#endif
|
124
emummc/source/emmc/sd.h
Normal file
124
emummc/source/emmc/sd.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* include/linux/mmc/sd.h
|
||||
*
|
||||
* Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef LINUX_MMC_SD_H
|
||||
#define LINUX_MMC_SD_H
|
||||
|
||||
/* SD commands type argument response */
|
||||
/* class 0 */
|
||||
/* This is basically the same command as for MMC with some quirks. */
|
||||
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
|
||||
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
|
||||
#define SD_SWITCH_VOLTAGE 11 /* ac R1 */
|
||||
|
||||
/* class 10 */
|
||||
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
|
||||
|
||||
/* class 5 */
|
||||
#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */
|
||||
#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */
|
||||
|
||||
/* Application commands */
|
||||
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
|
||||
#define SD_APP_SD_STATUS 13 /* adtc R1 */
|
||||
#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
|
||||
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
|
||||
#define SD_APP_SET_CLR_CARD_DETECT 42
|
||||
#define SD_APP_SEND_SCR 51 /* adtc R1 */
|
||||
|
||||
/* OCR bit definitions */
|
||||
#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */
|
||||
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
|
||||
#define SD_OCR_XPC (1 << 28) /* SDXC power control */
|
||||
#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */
|
||||
#define SD_OCR_VDD_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */
|
||||
|
||||
/*
|
||||
* SD_SWITCH argument format:
|
||||
*
|
||||
* [31] Check (0) or switch (1)
|
||||
* [30:24] Reserved (0)
|
||||
* [23:20] Function group 6
|
||||
* [19:16] Function group 5
|
||||
* [15:12] Function group 4
|
||||
* [11:8] Function group 3
|
||||
* [7:4] Function group 2
|
||||
* [3:0] Function group 1
|
||||
*/
|
||||
|
||||
/*
|
||||
* SD_SEND_IF_COND argument format:
|
||||
*
|
||||
* [31:12] Reserved (0)
|
||||
* [11:8] Host Voltage Supply Flags
|
||||
* [7:0] Check Pattern (0xAA)
|
||||
*/
|
||||
|
||||
/*
|
||||
* SCR field definitions
|
||||
*/
|
||||
#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */
|
||||
#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
|
||||
#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00-3.0X */
|
||||
#define SD_SCR_BUS_WIDTH_1 (1<<0)
|
||||
#define SD_SCR_BUS_WIDTH_4 (1<<2)
|
||||
|
||||
/*
|
||||
* SD bus widths
|
||||
*/
|
||||
#define SD_BUS_WIDTH_1 0
|
||||
#define SD_BUS_WIDTH_4 2
|
||||
|
||||
/*
|
||||
* SD bus speeds
|
||||
*/
|
||||
#define UHS_SDR12_BUS_SPEED 0
|
||||
#define HIGH_SPEED_BUS_SPEED 1
|
||||
#define UHS_SDR25_BUS_SPEED 1
|
||||
#define UHS_SDR50_BUS_SPEED 2
|
||||
#define UHS_SDR104_BUS_SPEED 3
|
||||
#define UHS_DDR50_BUS_SPEED 4
|
||||
#define HS400_BUS_SPEED 5
|
||||
|
||||
#define SD_MODE_HIGH_SPEED (1 << HIGH_SPEED_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED)
|
||||
#define SD_MODE_UHS_SDR104 (1 << UHS_SDR104_BUS_SPEED)
|
||||
#define SD_MODE_UHS_DDR50 (1 << UHS_DDR50_BUS_SPEED)
|
||||
|
||||
#define SD_DRIVER_TYPE_B 0x01
|
||||
#define SD_DRIVER_TYPE_A 0x02
|
||||
|
||||
#define SD_SET_CURRENT_LIMIT_200 0
|
||||
#define SD_SET_CURRENT_LIMIT_400 1
|
||||
#define SD_SET_CURRENT_LIMIT_600 2
|
||||
#define SD_SET_CURRENT_LIMIT_800 3
|
||||
|
||||
/*
|
||||
* SD_SWITCH mode
|
||||
*/
|
||||
#define SD_SWITCH_CHECK 0
|
||||
#define SD_SWITCH_SET 1
|
||||
|
||||
/*
|
||||
* SD_SWITCH function groups
|
||||
*/
|
||||
#define SD_SWITCH_GRP_ACCESS 0
|
||||
|
||||
/*
|
||||
* SD_SWITCH access modes
|
||||
*/
|
||||
#define SD_SWITCH_ACCESS_DEF 0
|
||||
#define SD_SWITCH_ACCESS_HS 1
|
||||
|
||||
#endif /* LINUX_MMC_SD_H */
|
1197
emummc/source/emmc/sdmmc.c
Normal file
1197
emummc/source/emmc/sdmmc.c
Normal file
File diff suppressed because it is too large
Load diff
113
emummc/source/emmc/sdmmc.h
Normal file
113
emummc/source/emmc/sdmmc.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SDMMC_H_
|
||||
#define _SDMMC_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "sdmmc_driver.h"
|
||||
|
||||
typedef struct _mmc_cid
|
||||
{
|
||||
u32 manfid;
|
||||
u8 prod_name[8];
|
||||
u8 card_bga;
|
||||
u8 prv;
|
||||
u32 serial;
|
||||
u16 oemid;
|
||||
u16 year;
|
||||
u8 hwrev;
|
||||
u8 fwrev;
|
||||
u8 month;
|
||||
} mmc_cid_t;
|
||||
|
||||
typedef struct _mmc_csd
|
||||
{
|
||||
u8 structure;
|
||||
u8 mmca_vsn;
|
||||
u16 cmdclass;
|
||||
u32 c_size;
|
||||
u32 r2w_factor;
|
||||
u32 max_dtr;
|
||||
u32 erase_size; /* In sectors */
|
||||
u32 read_blkbits;
|
||||
u32 write_blkbits;
|
||||
u32 capacity;
|
||||
u8 write_protect;
|
||||
u16 busspeed;
|
||||
} mmc_csd_t;
|
||||
|
||||
typedef struct _mmc_ext_csd
|
||||
{
|
||||
u8 rev;
|
||||
u32 sectors;
|
||||
int bkops; /* background support bit */
|
||||
int bkops_en; /* manual bkops enable bit */
|
||||
u8 ext_struct; /* 194 */
|
||||
u8 card_type; /* 196 */
|
||||
u8 bkops_status; /* 246 */
|
||||
u16 dev_version;
|
||||
u8 boot_mult;
|
||||
u8 rpmb_mult;
|
||||
} mmc_ext_csd_t;
|
||||
|
||||
typedef struct _sd_scr
|
||||
{
|
||||
u8 sda_vsn;
|
||||
u8 sda_spec3;
|
||||
u8 bus_widths;
|
||||
u8 cmds;
|
||||
} sd_scr_t;
|
||||
|
||||
typedef struct _sd_ssr
|
||||
{
|
||||
u8 bus_width;
|
||||
u8 speed_class;
|
||||
u8 uhs_grade;
|
||||
u8 video_class;
|
||||
u8 app_class;
|
||||
} sd_ssr_t;
|
||||
|
||||
/*! SDMMC storage context. */
|
||||
typedef struct _sdmmc_storage_t
|
||||
{
|
||||
sdmmc_t *sdmmc;
|
||||
u32 rca;
|
||||
int has_sector_access;
|
||||
u32 sec_cnt;
|
||||
int is_low_voltage;
|
||||
u32 partition;
|
||||
u8 raw_cid[0x10];
|
||||
u8 raw_csd[0x10];
|
||||
u8 raw_scr[8];
|
||||
u8 raw_ssr[0x40];
|
||||
mmc_cid_t cid;
|
||||
mmc_csd_t csd;
|
||||
mmc_ext_csd_t ext_csd;
|
||||
sd_scr_t scr;
|
||||
sd_ssr_t ssr;
|
||||
} sdmmc_storage_t;
|
||||
|
||||
int sdmmc_storage_end(sdmmc_storage_t *storage);
|
||||
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
|
||||
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
|
||||
int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);
|
||||
int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition);
|
||||
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);
|
||||
int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
|
||||
|
||||
#endif
|
1116
emummc/source/emmc/sdmmc_driver.c
Normal file
1116
emummc/source/emmc/sdmmc_driver.c
Normal file
File diff suppressed because it is too large
Load diff
127
emummc/source/emmc/sdmmc_driver.h
Normal file
127
emummc/source/emmc/sdmmc_driver.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SDMMC_DRIVER_H_
|
||||
#define _SDMMC_DRIVER_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "sdmmc_t210.h"
|
||||
|
||||
/*! SDMMC controller IDs. */
|
||||
#define SDMMC_1 0
|
||||
#define SDMMC_2 1
|
||||
#define SDMMC_3 2
|
||||
#define SDMMC_4 3
|
||||
|
||||
/*! SDMMC power types. */
|
||||
#define SDMMC_POWER_OFF 0
|
||||
#define SDMMC_POWER_1_8 1
|
||||
#define SDMMC_POWER_3_3 2
|
||||
|
||||
/*! SDMMC bus widths. */
|
||||
#define SDMMC_BUS_WIDTH_1 0
|
||||
#define SDMMC_BUS_WIDTH_4 1
|
||||
#define SDMMC_BUS_WIDTH_8 2
|
||||
|
||||
/*! SDMMC response types. */
|
||||
#define SDMMC_RSP_TYPE_0 0
|
||||
#define SDMMC_RSP_TYPE_1 1
|
||||
#define SDMMC_RSP_TYPE_2 2
|
||||
#define SDMMC_RSP_TYPE_3 3
|
||||
#define SDMMC_RSP_TYPE_4 4
|
||||
#define SDMMC_RSP_TYPE_5 5
|
||||
|
||||
/*! SDMMC mask interrupt status. */
|
||||
#define SDMMC_MASKINT_MASKED 0
|
||||
#define SDMMC_MASKINT_NOERROR -1
|
||||
#define SDMMC_MASKINT_ERROR -2
|
||||
|
||||
/*! SDMMC host control 2 */
|
||||
#define SDHCI_CTRL_UHS_MASK 0xFFF8
|
||||
#define SDHCI_CTRL_VDD_330 0xFFF7
|
||||
#define SDHCI_CTRL_VDD_180 8
|
||||
#define SDHCI_CTRL_EXEC_TUNING 0x40
|
||||
#define SDHCI_CTRL_TUNED_CLK 0x80
|
||||
#define SDHCI_HOST_VERSION_4_EN 0x1000
|
||||
#define SDHCI_ADDRESSING_64BIT_EN 0x2000
|
||||
#define SDHCI_CTRL_PRESET_VAL_EN 0x8000
|
||||
|
||||
/*! SD bus speeds. */
|
||||
#define UHS_SDR12_BUS_SPEED 0
|
||||
#define HIGH_SPEED_BUS_SPEED 1
|
||||
#define UHS_SDR25_BUS_SPEED 1
|
||||
#define UHS_SDR50_BUS_SPEED 2
|
||||
#define UHS_SDR104_BUS_SPEED 3
|
||||
#define UHS_DDR50_BUS_SPEED 4
|
||||
#define HS400_BUS_SPEED 5
|
||||
|
||||
/*! Helper for SWITCH command argument. */
|
||||
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))
|
||||
|
||||
/*! SDMMC controller context. */
|
||||
typedef struct _sdmmc_t
|
||||
{
|
||||
t210_sdmmc_t *regs;
|
||||
u32 id;
|
||||
u32 divisor;
|
||||
u32 clock_stopped;
|
||||
int no_sd;
|
||||
int sd_clock_enabled;
|
||||
int venclkctl_set;
|
||||
u32 venclkctl_tap;
|
||||
u32 expected_rsp_type;
|
||||
u64 dma_addr_fs;
|
||||
u64 dma_addr_next;
|
||||
u32 rsp[4];
|
||||
u32 rsp3;
|
||||
} sdmmc_t;
|
||||
|
||||
/*! SDMMC command. */
|
||||
typedef struct _sdmmc_cmd_t
|
||||
{
|
||||
u16 cmd;
|
||||
u32 arg;
|
||||
u32 rsp_type;
|
||||
u32 check_busy;
|
||||
} sdmmc_cmd_t;
|
||||
|
||||
/*! SDMMC request. */
|
||||
typedef struct _sdmmc_req_t
|
||||
{
|
||||
void *buf;
|
||||
u32 blksize;
|
||||
u32 num_sectors;
|
||||
int is_write;
|
||||
int is_multi_block;
|
||||
int is_auto_cmd12;
|
||||
} sdmmc_req_t;
|
||||
|
||||
int sdmmc_get_voltage(sdmmc_t *sdmmc);
|
||||
u32 sdmmc_get_bus_width(sdmmc_t *sdmmc);
|
||||
void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width);
|
||||
void sdmmc_get_venclkctl(sdmmc_t *sdmmc);
|
||||
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type);
|
||||
void sdmmc_sd_clock_ctrl(sdmmc_t *sdmmc, int no_sd);
|
||||
int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type);
|
||||
int sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd);
|
||||
int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp);
|
||||
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int no_sd);
|
||||
void sdmmc_end(sdmmc_t *sdmmc);
|
||||
void sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy);
|
||||
int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out);
|
||||
int sdmmc_enable_low_voltage(sdmmc_t *sdmmc);
|
||||
|
||||
#endif
|
132
emummc/source/emmc/sdmmc_t210.h
Normal file
132
emummc/source/emmc/sdmmc_t210.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SDMMC_T210_H_
|
||||
#define _SDMMC_T210_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
#define TEGRA_MMC_PWRCTL_SD_BUS_POWER 0x1
|
||||
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8 0xA
|
||||
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_0 0xC
|
||||
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3 0xE
|
||||
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_MASK 0xF1
|
||||
|
||||
#define TEGRA_MMC_HOSTCTL_1BIT 0x00
|
||||
#define TEGRA_MMC_HOSTCTL_4BIT 0x02
|
||||
#define TEGRA_MMC_HOSTCTL_8BIT 0x20
|
||||
|
||||
#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE 0x1
|
||||
#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_STABLE 0x2
|
||||
#define TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE 0x4
|
||||
#define TEGRA_MMC_CLKCON_CLKGEN_SELECT 0x20
|
||||
|
||||
#define TEGRA_MMC_SWRST_SW_RESET_FOR_ALL 0x1
|
||||
#define TEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE 0x2
|
||||
#define TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE 0x4
|
||||
|
||||
#define TEGRA_MMC_TRNMOD_DMA_ENABLE 0x1
|
||||
#define TEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE 0x2
|
||||
#define TEGRA_MMC_TRNMOD_AUTO_CMD12 0x4
|
||||
#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_WRITE 0x0
|
||||
#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ 0x10
|
||||
#define TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT 0x20
|
||||
|
||||
#define TEGRA_MMC_TRNMOD_CMD_CRC_CHECK 0x8
|
||||
#define TEGRA_MMC_TRNMOD_CMD_INDEX_CHECK 0x10
|
||||
#define TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER 0x20
|
||||
|
||||
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_MASK 0x3
|
||||
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE 0x0
|
||||
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136 0x1
|
||||
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48 0x2
|
||||
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY 0x3
|
||||
|
||||
#define TEGRA_MMC_NORINTSTS_CMD_COMPLETE 0x1
|
||||
#define TEGRA_MMC_NORINTSTS_XFER_COMPLETE 0x2
|
||||
#define TEGRA_MMC_NORINTSTS_DMA_INTERRUPT 0x8
|
||||
#define TEGRA_MMC_NORINTSTS_ERR_INTERRUPT 0x8000
|
||||
#define TEGRA_MMC_NORINTSTS_CMD_TIMEOUT 0x10000
|
||||
|
||||
#define TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY 0x20
|
||||
|
||||
typedef struct _t210_sdmmc_t
|
||||
{
|
||||
vu32 sysad;
|
||||
vu16 blksize;
|
||||
vu16 blkcnt;
|
||||
vu32 argument;
|
||||
vu16 trnmod;
|
||||
vu16 cmdreg;
|
||||
vu32 rspreg0;
|
||||
vu32 rspreg1;
|
||||
vu32 rspreg2;
|
||||
vu32 rspreg3;
|
||||
vu32 bdata;
|
||||
vu32 prnsts;
|
||||
vu8 hostctl;
|
||||
vu8 pwrcon;
|
||||
vu8 blkgap;
|
||||
vu8 wakcon;
|
||||
vu16 clkcon;
|
||||
vu8 timeoutcon;
|
||||
vu8 swrst;
|
||||
vu16 norintsts;
|
||||
vu16 errintsts;
|
||||
vu16 norintstsen;
|
||||
vu16 errintstsen;
|
||||
vu16 norintsigen;
|
||||
vu16 errintsigen;
|
||||
vu16 acmd12errsts;
|
||||
vu16 hostctl2;
|
||||
vu32 capareg;
|
||||
vu32 capareg_1;
|
||||
vu32 maxcurr;
|
||||
vu8 res3[4];
|
||||
vu16 setacmd12err;
|
||||
vu16 setinterr;
|
||||
vu8 admaerr;
|
||||
vu8 res4[3];
|
||||
vu32 admaaddr;
|
||||
vu32 admaaddr_hi;
|
||||
vu8 res5[156];
|
||||
vu16 slotintstatus;
|
||||
vu16 hcver;
|
||||
vu32 venclkctl;
|
||||
vu32 venspictl;
|
||||
vu32 venspiintsts;
|
||||
vu32 venceatactl;
|
||||
vu32 venbootctl;
|
||||
vu32 venbootacktout;
|
||||
vu32 venbootdattout;
|
||||
vu32 vendebouncecnt;
|
||||
vu32 venmiscctl;
|
||||
vu32 res6[34];
|
||||
vu32 veniotrimctl;
|
||||
vu32 vendllcal;
|
||||
vu8 res7[8];
|
||||
vu32 dllcfgstatus;
|
||||
vu32 ventunctl0;
|
||||
vu32 field_1C4;
|
||||
vu8 field_1C8[24];
|
||||
vu32 sdmemcmppadctl;
|
||||
vu32 autocalcfg;
|
||||
vu32 autocalintval;
|
||||
vu32 autocalsts;
|
||||
vu32 iospare;
|
||||
} t210_sdmmc_t;
|
||||
|
||||
#endif
|
450
emummc/source/emuMMC/emummc.c
Normal file
450
emummc/source/emuMMC/emummc.c
Normal file
|
@ -0,0 +1,450 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../soc/gpio.h"
|
||||
#include "../utils/fatal.h"
|
||||
#include "../libs/fatfs/diskio.h"
|
||||
#include "emummc.h"
|
||||
#include "emummc_ctx.h"
|
||||
|
||||
static bool storageMMCinitialized = false;
|
||||
static bool storageSDinitialized = false;
|
||||
|
||||
// hekate sdmmmc vars
|
||||
sdmmc_t sdmmc;
|
||||
sdmmc_storage_t storage;
|
||||
sdmmc_t sd_sdmmc;
|
||||
sdmmc_storage_t sd_storage;
|
||||
|
||||
// init vars
|
||||
bool custom_driver = true;
|
||||
extern const volatile emuMMC_ctx_t emuMMC_ctx;
|
||||
|
||||
// FS funcs
|
||||
_sdmmc_accessor_gc sdmmc_accessor_gc;
|
||||
_sdmmc_accessor_sd sdmmc_accessor_sd;
|
||||
_sdmmc_accessor_nand sdmmc_accessor_nand;
|
||||
_lock_mutex lock_mutex;
|
||||
_unlock_mutex unlock_mutex;
|
||||
|
||||
// FS misc
|
||||
void *sd_mutex;
|
||||
void *nand_mutex;
|
||||
volatile int *active_partition;
|
||||
volatile Handle *sdmmc_das_handle;
|
||||
|
||||
// FatFS
|
||||
static bool fat_mounted = false;
|
||||
static file_based_ctxt f_emu;
|
||||
|
||||
static void _sdmmc_ensure_device_attached(void)
|
||||
{
|
||||
// This ensures that the sd device address space handle is always attached,
|
||||
// even if FS hasn't attached it
|
||||
static bool did_attach = false;
|
||||
if (!did_attach)
|
||||
{
|
||||
svcAttachDeviceAddressSpace(DeviceName_SDMMC1A, *sdmmc_das_handle);
|
||||
did_attach = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void _sdmmc_ensure_initialized(void)
|
||||
{
|
||||
// The boot sysmodule will eventually kill power to SD. Detect this, and reinitialize when it happens.
|
||||
static bool init_done = false;
|
||||
if (!init_done)
|
||||
{
|
||||
if (gpio_read(GPIO_PORT_E, GPIO_PIN_4) == 0)
|
||||
{
|
||||
sdmmc_finalize();
|
||||
sdmmc_initialize();
|
||||
init_done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sdmmc_finalize(void)
|
||||
{
|
||||
if (!sdmmc_storage_end(&sd_storage))
|
||||
{
|
||||
fatal_abort(Fatal_InitSD);
|
||||
}
|
||||
storageSDinitialized = false;
|
||||
}
|
||||
|
||||
static void _file_based_update_filename(char *outFilename, u32 sd_path_len, u32 part_idx)
|
||||
{
|
||||
if (part_idx < 10)
|
||||
{
|
||||
outFilename[sd_path_len] = '0';
|
||||
itoa(part_idx, &outFilename[sd_path_len + 1], 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
itoa(part_idx, &outFilename[sd_path_len], 10);
|
||||
}
|
||||
}
|
||||
|
||||
static void _file_based_emmc_finalize(void)
|
||||
{
|
||||
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_File) && fat_mounted)
|
||||
{
|
||||
// Close all open handles.
|
||||
f_close(f_emu.fp_boot0);
|
||||
f_close(f_emu.fp_boot1);
|
||||
|
||||
for (int i = 0; i < f_emu.parts; i++)
|
||||
f_close(f_emu.fp_gpp[i]);
|
||||
|
||||
// Force unmount FAT volume.
|
||||
f_mount(NULL, "", 1);
|
||||
|
||||
fat_mounted = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void _file_based_emmc_initialize(void)
|
||||
{
|
||||
char path[sizeof(emuMMC_ctx.storagePath) + 0x20];
|
||||
memset(&path, 0, sizeof(path));
|
||||
memset(&f_emu, 0, sizeof(file_based_ctxt));
|
||||
|
||||
memcpy(path, (void *)emuMMC_ctx.storagePath, sizeof(emuMMC_ctx.storagePath));
|
||||
strcat(path, "/eMMC");
|
||||
int path_len = strlen(path);
|
||||
|
||||
// Open BOOT0 physical partition.
|
||||
f_emu.fp_boot0 = (FIL *)malloc(sizeof(FIL));
|
||||
memcpy(path + path_len, "BOOT0", 6);
|
||||
if (f_open(f_emu.fp_boot0, path, FA_READ | FA_WRITE) != FR_OK)
|
||||
fatal_abort(Fatal_InitSD);
|
||||
|
||||
// Open BOOT1 physical partition.
|
||||
f_emu.fp_boot1 = (FIL *)malloc(sizeof(FIL));
|
||||
memcpy(path + path_len, "BOOT1", 6);
|
||||
if (f_open(f_emu.fp_boot1, path, FA_READ | FA_WRITE) != FR_OK)
|
||||
fatal_abort(Fatal_InitSD);
|
||||
|
||||
// Open handles for GPP physical partition files.
|
||||
_file_based_update_filename(path, path_len, 00);
|
||||
if (f_open(f_emu.fp_gpp[0], path, FA_READ | FA_WRITE) != FR_OK)
|
||||
fatal_abort(Fatal_InitSD);
|
||||
|
||||
f_emu.part_size = f_size(f_emu.fp_gpp[0]);
|
||||
|
||||
// Iterate folder for split parts and stop if next doesn't exist.
|
||||
// Supports up to 32 parts of any size.
|
||||
// TODO: decide on max parts and define them. (hekate produces up to 30 parts on 1GB mode.)
|
||||
for (f_emu.parts = 1; f_emu.parts < 32; f_emu.parts++)
|
||||
{
|
||||
f_emu.fp_gpp[f_emu.parts] = (FIL *)malloc(sizeof(FIL));
|
||||
_file_based_update_filename(path, path_len, f_emu.parts);
|
||||
|
||||
if (f_open(f_emu.fp_gpp[f_emu.parts], path, FA_READ | FA_WRITE) != FR_OK)
|
||||
{
|
||||
free(f_emu.fp_gpp[f_emu.parts]);
|
||||
|
||||
// Check if single file.
|
||||
if (f_emu.parts == 1)
|
||||
f_emu.parts = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool sdmmc_initialize(void)
|
||||
{
|
||||
if (!storageMMCinitialized)
|
||||
{
|
||||
if (sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4))
|
||||
{
|
||||
if (sdmmc_storage_set_mmc_partition(&storage, FS_EMMC_PARTITION_GPP))
|
||||
storageMMCinitialized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal_abort(Fatal_InitMMC);
|
||||
}
|
||||
}
|
||||
|
||||
if (!storageSDinitialized)
|
||||
{
|
||||
if (sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, SDMMC_1, SDMMC_BUS_WIDTH_4, 11))
|
||||
{
|
||||
storageSDinitialized = true;
|
||||
|
||||
// File based emummc.
|
||||
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_File) && !fat_mounted)
|
||||
{
|
||||
f_emu.sd_fs = (FATFS *)malloc(sizeof(FATFS));
|
||||
if (f_mount(f_emu.sd_fs, "", 1) != FR_OK)
|
||||
fatal_abort(Fatal_InitSD);
|
||||
else
|
||||
fat_mounted = true;
|
||||
|
||||
_file_based_emmc_initialize();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal_abort(Fatal_InitSD);
|
||||
}
|
||||
}
|
||||
|
||||
return storageMMCinitialized && storageSDinitialized;
|
||||
}
|
||||
|
||||
// FS DMA calculations.
|
||||
intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors)
|
||||
{
|
||||
int dma_buf_idx = 0;
|
||||
char *_buf = (char *)buf;
|
||||
char *actual_buf_start = _buf;
|
||||
char *actual_buf_end = &_buf[512 * num_sectors];
|
||||
char *dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer;
|
||||
|
||||
if (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer_size])
|
||||
{
|
||||
dma_buf_idx = FS_SDMMC_EMMC;
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer;
|
||||
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer_size])
|
||||
{
|
||||
dma_buf_idx = FS_SDMMC_SD;
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer;
|
||||
dma_buf_idx = FS_SDMMC_GC;
|
||||
}
|
||||
}
|
||||
|
||||
intptr_t admaaddr = (intptr_t)&_this->parent->dmaBuffers[dma_buf_idx].device_addr_buffer_masked[actual_buf_start - dma_buffer_start];
|
||||
|
||||
return admaaddr;
|
||||
}
|
||||
|
||||
sdmmc_accessor_t *sdmmc_accessor_get(int mmc_id)
|
||||
{
|
||||
sdmmc_accessor_t *_this;
|
||||
switch (mmc_id)
|
||||
{
|
||||
case FS_SDMMC_EMMC:
|
||||
_this = sdmmc_accessor_nand();
|
||||
break;
|
||||
case FS_SDMMC_SD:
|
||||
_this = sdmmc_accessor_sd();
|
||||
break;
|
||||
case FS_SDMMC_GC:
|
||||
_this = sdmmc_accessor_gc();
|
||||
break;
|
||||
default:
|
||||
fatal_abort(Fatal_InvalidAccessor);
|
||||
}
|
||||
|
||||
return _this;
|
||||
}
|
||||
|
||||
void mutex_lock_handler(int mmc_id)
|
||||
{
|
||||
lock_mutex(sd_mutex);
|
||||
lock_mutex(nand_mutex);
|
||||
}
|
||||
|
||||
void mutex_unlock_handler(int mmc_id)
|
||||
{
|
||||
unlock_mutex(nand_mutex);
|
||||
unlock_mutex(sd_mutex);
|
||||
}
|
||||
|
||||
int sdmmc_nand_get_active_partition_index()
|
||||
{
|
||||
switch (*active_partition)
|
||||
{
|
||||
case FS_EMMC_PARTITION_GPP:
|
||||
return 2;
|
||||
case FS_EMMC_PARTITION_BOOT1:
|
||||
return 1;
|
||||
case FS_EMMC_PARTITION_BOOT0:
|
||||
return 0;
|
||||
}
|
||||
|
||||
fatal_abort(Fatal_InvalidAccessor);
|
||||
}
|
||||
|
||||
static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned int num_sectors, bool is_write)
|
||||
{
|
||||
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD))
|
||||
{
|
||||
// raw partition sector offset: emuMMC_ctx.EMMC_StoragePartitionOffset.
|
||||
sector += emuMMC_ctx.EMMC_StoragePartitionOffset;
|
||||
// Set physical partition offset.
|
||||
sector += (sdmmc_nand_get_active_partition_index() * BOOT_PARTITION_SIZE);
|
||||
if (!is_write)
|
||||
return sdmmc_storage_read(&sd_storage, sector, num_sectors, buf);
|
||||
else
|
||||
return sdmmc_storage_write(&sd_storage, sector, num_sectors, buf);
|
||||
}
|
||||
|
||||
// File based emummc.
|
||||
FIL *fp_tmp = NULL;
|
||||
switch (*active_partition)
|
||||
{
|
||||
case FS_EMMC_PARTITION_GPP:
|
||||
if (f_emu.parts)
|
||||
{
|
||||
fp_tmp = f_emu.fp_gpp[sector / f_emu.part_size];
|
||||
sector = sector % f_emu.part_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_tmp = f_emu.fp_gpp[0];
|
||||
}
|
||||
break;
|
||||
case FS_EMMC_PARTITION_BOOT1:
|
||||
fp_tmp = f_emu.fp_boot1;
|
||||
break;
|
||||
case FS_EMMC_PARTITION_BOOT0:
|
||||
fp_tmp = f_emu.fp_boot0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (f_lseek(fp_tmp, sector << 9) != FR_OK)
|
||||
{
|
||||
; //TODO. Out of range. close stuff and fatal?
|
||||
}
|
||||
|
||||
if (!is_write)
|
||||
return !(f_read(fp_tmp, buf, num_sectors << 9, NULL));
|
||||
else
|
||||
return !(f_write(fp_tmp, buf, num_sectors << 9, NULL));
|
||||
}
|
||||
|
||||
// FS read wrapper.
|
||||
uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned int sector, unsigned int num_sectors)
|
||||
{
|
||||
sdmmc_accessor_t *_this;
|
||||
uint64_t read_res;
|
||||
|
||||
_this = sdmmc_accessor_get(mmc_id);
|
||||
|
||||
if (_this != NULL)
|
||||
{
|
||||
if (mmc_id == FS_SDMMC_EMMC || mmc_id == FS_SDMMC_SD)
|
||||
{
|
||||
mutex_lock_handler(mmc_id);
|
||||
// Make sure we're attached to the device address space.
|
||||
_sdmmc_ensure_device_attached();
|
||||
// Make sure we're still initialized if boot killed sd card power.
|
||||
_sdmmc_ensure_initialized();
|
||||
}
|
||||
|
||||
if (mmc_id == FS_SDMMC_EMMC)
|
||||
{
|
||||
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
|
||||
|
||||
// Call hekates driver.
|
||||
if (emummc_read_write_inner(buf, sector, num_sectors, false))
|
||||
{
|
||||
mutex_unlock_handler(mmc_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_unlock_handler(mmc_id);
|
||||
return FS_READ_WRITE_ERROR;
|
||||
}
|
||||
|
||||
if (mmc_id == FS_SDMMC_SD)
|
||||
{
|
||||
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
|
||||
|
||||
// Call hekates driver.
|
||||
if (sdmmc_storage_read(&sd_storage, sector, num_sectors, buf))
|
||||
{
|
||||
mutex_unlock_handler(mmc_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_unlock_handler(mmc_id);
|
||||
return FS_READ_WRITE_ERROR;
|
||||
}
|
||||
|
||||
read_res = _this->vtab->read_write(_this, sector, num_sectors, buf, bufSize, 1);
|
||||
return read_res;
|
||||
}
|
||||
|
||||
fatal_abort(Fatal_ReadNoAccessor);
|
||||
}
|
||||
|
||||
// FS write wrapper.
|
||||
uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_sectors, void *buf, uint64_t bufSize)
|
||||
{
|
||||
sdmmc_accessor_t *_this;
|
||||
uint64_t write_res;
|
||||
|
||||
_this = sdmmc_accessor_get(mmc_id);
|
||||
|
||||
if (_this != NULL)
|
||||
{
|
||||
if (mmc_id == FS_SDMMC_EMMC)
|
||||
{
|
||||
mutex_lock_handler(mmc_id);
|
||||
|
||||
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
|
||||
|
||||
// Call hekates driver.
|
||||
if (emummc_read_write_inner(buf, sector, num_sectors, true))
|
||||
{
|
||||
mutex_unlock_handler(mmc_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_unlock_handler(mmc_id);
|
||||
return FS_READ_WRITE_ERROR;
|
||||
}
|
||||
|
||||
if (mmc_id == FS_SDMMC_SD)
|
||||
{
|
||||
mutex_lock_handler(mmc_id);
|
||||
|
||||
sector += 0;
|
||||
sd_storage.sdmmc->dma_addr_fs = (u64)sdmmc_calculate_dma_addr(_this, buf, num_sectors);
|
||||
|
||||
// Call hekates driver.
|
||||
if (sdmmc_storage_write(&sd_storage, sector, num_sectors, buf))
|
||||
{
|
||||
mutex_unlock_handler(mmc_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_unlock_handler(mmc_id);
|
||||
return FS_READ_WRITE_ERROR;
|
||||
}
|
||||
|
||||
write_res = _this->vtab->read_write(_this, sector, num_sectors, buf, bufSize, 0);
|
||||
return write_res;
|
||||
}
|
||||
|
||||
fatal_abort(Fatal_WriteNoAccessor);
|
||||
}
|
73
emummc/source/emuMMC/emummc.h
Normal file
73
emummc/source/emuMMC/emummc.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __EMUMMC_H__
|
||||
#define __EMUMMC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../emmc/sdmmc.h"
|
||||
#include "../soc/i2c.h"
|
||||
#include "../soc/gpio.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../FS/FS.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
|
||||
// FS typedefs
|
||||
typedef sdmmc_accessor_t *(*_sdmmc_accessor_gc)();
|
||||
typedef sdmmc_accessor_t *(*_sdmmc_accessor_sd)();
|
||||
typedef sdmmc_accessor_t *(*_sdmmc_accessor_nand)();
|
||||
typedef void (*_lock_mutex)(void *mtx);
|
||||
typedef void (*_unlock_mutex)(void *mtx);
|
||||
|
||||
bool sdmmc_initialize(void);
|
||||
void sdmmc_finalize(void);
|
||||
int sdmmc_nand_get_active_partition_index();
|
||||
sdmmc_accessor_t *sdmmc_accessor_get(int mmc_id);
|
||||
|
||||
void mutex_lock_handler(int mmc_id);
|
||||
void mutex_unlock_handler(int mmc_id);
|
||||
|
||||
intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors);
|
||||
|
||||
uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned int sector, unsigned int num_sectors);
|
||||
uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_sectors, void *buf, uint64_t bufSize);
|
||||
|
||||
// TODO: check if FatFS internal buffers are good (perf wise) to have a x16 alignment.
|
||||
typedef struct _file_based_ctxt
|
||||
{
|
||||
uint64_t parts;
|
||||
uint64_t part_size;
|
||||
FATFS *sd_fs;
|
||||
FIL *fp_boot0;
|
||||
FIL *fp_boot1;
|
||||
FIL *fp_gpp[32];
|
||||
} file_based_ctxt;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EMUMMC_H__ */
|
56
emummc/source/emuMMC/emummc_ctx.h
Normal file
56
emummc/source/emuMMC/emummc_ctx.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __EMUMMC_CTX_H__
|
||||
#define __EMUMMC_CTX_H__
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "../FS/FS_versions.h"
|
||||
|
||||
#define EMUMMC_STORAGE_MAGIC 0x30534645 /* EFS0, EmuFS0 */
|
||||
#define EMUMMC_MAX_DIR_LENGTH 0x7F
|
||||
|
||||
enum emuMMC_Type
|
||||
{
|
||||
// EMMC Device raw
|
||||
emuMMC_EMMC = 0,
|
||||
|
||||
// SD Device raw
|
||||
emuMMC_SD,
|
||||
// SD Device File
|
||||
emuMMC_SD_File,
|
||||
|
||||
emuMMC_MAX
|
||||
};
|
||||
|
||||
typedef struct _emuMMC_ctx_t
|
||||
{
|
||||
u32 magic;
|
||||
u32 id;
|
||||
enum FS_VER fs_ver;
|
||||
enum emuMMC_Type EMMC_Type;
|
||||
enum emuMMC_Type SD_Type;
|
||||
|
||||
/* Partition based */
|
||||
u64 EMMC_StoragePartitionOffset;
|
||||
u64 SD_StoragePartitionOffset;
|
||||
|
||||
/* File-Based */
|
||||
char storagePath[EMUMMC_MAX_DIR_LENGTH+1];
|
||||
} emuMMC_ctx_t, *PemuMMC_ctx_t;
|
||||
|
||||
#endif /* __EMUMMC_CTX_H__ */
|
72
emummc/source/libs/fatfs/diskio.c
Normal file
72
emummc/source/libs/fatfs/diskio.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* If a working storage control module is available, it should be */
|
||||
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||
/* This is an example of glue functions to attach various exsisting */
|
||||
/* storage control modules to the FatFs module with a defined API. */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "../../emmc/sdmmc.h"
|
||||
|
||||
extern sdmmc_storage_t sd_storage;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
DRESULT disk_read (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
return RES_OK;
|
||||
}
|
79
emummc/source/libs/fatfs/diskio.h
Normal file
79
emummc/source/libs/fatfs/diskio.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../utils/types.h"
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
6623
emummc/source/libs/fatfs/ff.c
Normal file
6623
emummc/source/libs/fatfs/ff.c
Normal file
File diff suppressed because it is too large
Load diff
379
emummc/source/libs/fatfs/ff.h
Normal file
379
emummc/source/libs/fatfs/ff.h
Normal file
|
@ -0,0 +1,379 @@
|
|||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.13c /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2018, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef FF_DEFINED
|
||||
#define FF_DEFINED 86604 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../utils/types.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#endif
|
||||
|
||||
#if FF_STR_VOLUME_ID
|
||||
#ifndef FF_VOLUME_STRS
|
||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#ifndef _INC_TCHAR
|
||||
#define _INC_TCHAR
|
||||
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) u8 ## x
|
||||
#define _TEXT(x) u8 ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
|
||||
typedef DWORD TCHAR;
|
||||
#define _T(x) U ## x
|
||||
#define _TEXT(x) U ## x
|
||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
|
||||
#error Wrong FF_LFN_UNICODE setting
|
||||
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
typedef DWORD FSIZE_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
||||
BYTE pdrv; /* Associated physical drive */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||
#endif
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||
DWORD fsize; /* Size of an FAT [sectors] */
|
||||
DWORD volbase; /* Volume base sector */
|
||||
DWORD fatbase; /* FAT base sector */
|
||||
DWORD dirbase; /* Root directory base sector/cluster */
|
||||
DWORD database; /* Data base sector */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD bitbase; /* Allocation bitmap base sector */
|
||||
#endif
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the hosting volume of this object */
|
||||
WORD id; /* Hosting volume mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !FF_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[12 + 1]; /* File name */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
|
||||
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
||||
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
||||
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
||||
#endif
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access mode and open method flags (3rd argument of f_open) */
|
||||
#define FA_READ 0x01
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA_OPEN_APPEND 0x30
|
||||
|
||||
/* Fast seek controls (2nd argument of f_lseek) */
|
||||
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||
|
||||
/* Format options (2nd argument of f_mkfs) */
|
||||
#define FM_FAT 0x01
|
||||
#define FM_FAT32 0x02
|
||||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
#define FS_EXFAT 4
|
||||
|
||||
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FF_DEFINED */
|
287
emummc/source/libs/fatfs/ffconf.h
Normal file
287
emummc/source/libs/fatfs/ffconf.h
Normal file
|
@ -0,0 +1,287 @@
|
|||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs Functional Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 86604 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: Basic functions are fully enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 2
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 1
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE 850
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#define FF_USE_LFN 3
|
||||
#define FF_MAX_LFN 255
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
|
||||
/ specification.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#define FF_LFN_UNICODE 0
|
||||
/* This option switches the character encoding on the API when LFN is enabled.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
||||
/
|
||||
/ Also behavior of string I/O functions will be affected by this option.
|
||||
/ When LFN is not enabled, this option has no effect. */
|
||||
|
||||
|
||||
#define FF_LFN_BUF 255
|
||||
#define FF_SFN_BUF 12
|
||||
/* This set of options defines size of file name members in the FILINFO structure
|
||||
/ which is used to read out directory items. These values should be suffcient for
|
||||
/ the file names to read. The maximum possible length of the read file name depends
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 0
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 0
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "sd"
|
||||
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
|
||||
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
|
||||
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
|
||||
/ not defined, a user defined volume string table needs to be defined as:
|
||||
/
|
||||
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
|
||||
*/
|
||||
|
||||
|
||||
#define FF_MULTI_PARTITION 0
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
|
||||
#define FF_MIN_SS 512
|
||||
#define FF_MAX_SS 512
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 1
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define FF_FS_NORTC 1
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2019
|
||||
/* The option FF_FS_NORTC switches timestamp function. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
|
||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_LOCK 0
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
#define FF_FS_REENTRANT 0
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#define FF_SYNC_t HANDLE
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
39
emummc/source/libs/fatfs/ffsystem.c
Normal file
39
emummc/source/libs/fatfs/ffsystem.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*------------------------------------------------------------------------*/
|
||||
/* Sample Code of OS Dependent Functions for FatFs */
|
||||
/* (C) ChaN, 2018 */
|
||||
/* (C) CTCaer, 2018 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "ff.h"
|
||||
#include "../../utils/types.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Free a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free (nothing to do if null) */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Free the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
627
emummc/source/libs/fatfs/ffunicode.c
Normal file
627
emummc/source/libs/fatfs/ffunicode.c
Normal file
|
@ -0,0 +1,627 @@
|
|||
/*------------------------------------------------------------------------*/
|
||||
/* Unicode handling functions for FatFs R0.13c */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This module will occupy a huge memory in the .const section when the /
|
||||
/ FatFs is configured for LFN with DBCS. If the system has any Unicode /
|
||||
/ utilitiy for the code conversion, this module should be modified to use /
|
||||
/ that function to avoid silly memory consumption. /
|
||||
/-------------------------------------------------------------------------*/
|
||||
/*
|
||||
/ Copyright (C) 2018, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
/
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
*/
|
||||
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
#if FF_USE_LFN /* This module will be blanked at non-LFN configuration */
|
||||
|
||||
#if FF_DEFINED != 86604 /* Revision ID */
|
||||
#error Wrong include file (ff.h).
|
||||
#endif
|
||||
|
||||
#define MERGE2(a, b) a ## b
|
||||
#define CVTBL(tbl, cp) MERGE2(tbl, cp)
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Code Conversion Tables */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */
|
||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
||||
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */
|
||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
||||
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */
|
||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
||||
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
||||
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
||||
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table */
|
||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
||||
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
||||
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
|
||||
0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
|
||||
0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
|
||||
0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */
|
||||
0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
|
||||
0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
|
||||
0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
|
||||
0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,
|
||||
0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,
|
||||
0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,
|
||||
0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,
|
||||
0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */
|
||||
0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
|
||||
0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
|
||||
0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,
|
||||
0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,
|
||||
0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,
|
||||
0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OEM <==> Unicode conversions for static code page configuration */
|
||||
/* SBCS fixed code page */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900
|
||||
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
DWORD uni, /* UTF-16 encoded character to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
WCHAR c = 0;
|
||||
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
|
||||
|
||||
|
||||
if (uni < 0x80) { /* ASCII? */
|
||||
c = (WCHAR)uni;
|
||||
|
||||
} else { /* Non-ASCII */
|
||||
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */
|
||||
for (c = 0; c < 0x80 && uni != p[c]; c++) ;
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
WCHAR oem, /* OEM code to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
WCHAR c = 0;
|
||||
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
|
||||
|
||||
|
||||
if (oem < 0x80) { /* ASCII? */
|
||||
c = oem;
|
||||
|
||||
} else { /* Extended char */
|
||||
if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */
|
||||
if (oem < 0x100) c = p[oem - 0x80];
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OEM <==> Unicode conversions for static code page configuration */
|
||||
/* DBCS fixed code page */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#if FF_CODE_PAGE >= 900
|
||||
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
DWORD uni, /* UTF-16 encoded character to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0, uc;
|
||||
UINT i = 0, n, li, hi;
|
||||
|
||||
|
||||
if (uni < 0x80) { /* ASCII? */
|
||||
c = (WCHAR)uni;
|
||||
|
||||
} else { /* Non-ASCII */
|
||||
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */
|
||||
uc = (WCHAR)uni;
|
||||
p = CVTBL(uni2oem, FF_CODE_PAGE);
|
||||
hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1;
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
i = li + (hi - li) / 2;
|
||||
if (uc == p[i * 2]) break;
|
||||
if (uc > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
}
|
||||
}
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
WCHAR oem, /* OEM code to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0;
|
||||
UINT i = 0, n, li, hi;
|
||||
|
||||
|
||||
if (oem < 0x80) { /* ASCII? */
|
||||
c = oem;
|
||||
|
||||
} else { /* Extended char */
|
||||
if (cp == FF_CODE_PAGE) { /* Is it valid code page? */
|
||||
p = CVTBL(oem2uni, FF_CODE_PAGE);
|
||||
hi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1;
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
i = li + (hi - li) / 2;
|
||||
if (oem == p[i * 2]) break;
|
||||
if (oem > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
}
|
||||
}
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OEM <==> Unicode conversions for dynamic code page configuration */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#if FF_CODE_PAGE == 0
|
||||
|
||||
static const WORD cp_code[] = { 437, 720, 737, 771, 775, 850, 852, 855, 857, 860, 861, 862, 863, 864, 865, 866, 869, 0};
|
||||
static const WCHAR* const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0};
|
||||
|
||||
|
||||
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
DWORD uni, /* UTF-16 encoded character to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0, uc;
|
||||
UINT i, n, li, hi;
|
||||
|
||||
|
||||
if (uni < 0x80) { /* ASCII? */
|
||||
c = (WCHAR)uni;
|
||||
|
||||
} else { /* Non-ASCII */
|
||||
if (uni < 0x10000) { /* Is it in BMP? */
|
||||
uc = (WCHAR)uni;
|
||||
p = 0;
|
||||
if (cp < 900) { /* SBCS */
|
||||
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get conversion table */
|
||||
p = cp_table[i];
|
||||
if (p) { /* Is it valid code page ? */
|
||||
for (c = 0; c < 0x80 && uc != p[c]; c++) ; /* Find OEM code in the table */
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
} else { /* DBCS */
|
||||
switch (cp) { /* Get conversion table */
|
||||
case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break;
|
||||
case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break;
|
||||
case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break;
|
||||
case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break;
|
||||
}
|
||||
if (p) { /* Is it valid code page? */
|
||||
li = 0;
|
||||
for (n = 16; n; n--) { /* Find OEM code */
|
||||
i = li + (hi - li) / 2;
|
||||
if (uc == p[i * 2]) break;
|
||||
if (uc > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
}
|
||||
}
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
WCHAR oem, /* OEM code to be converted (DBC if >=0x100) */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0;
|
||||
UINT i, n, li, hi;
|
||||
|
||||
|
||||
if (oem < 0x80) { /* ASCII? */
|
||||
c = oem;
|
||||
|
||||
} else { /* Extended char */
|
||||
p = 0;
|
||||
if (cp < 900) { /* SBCS */
|
||||
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */
|
||||
p = cp_table[i];
|
||||
if (p) { /* Is it a valid CP ? */
|
||||
if (oem < 0x100) c = p[oem - 0x80];
|
||||
}
|
||||
} else { /* DBCS */
|
||||
switch (cp) {
|
||||
case 932 : p = oem2uni932; hi = sizeof oem2uni932 / 4 - 1; break;
|
||||
case 936 : p = oem2uni936; hi = sizeof oem2uni936 / 4 - 1; break;
|
||||
case 949 : p = oem2uni949; hi = sizeof oem2uni949 / 4 - 1; break;
|
||||
case 950 : p = oem2uni950; hi = sizeof oem2uni950 / 4 - 1; break;
|
||||
}
|
||||
if (p) {
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
i = li + (hi - li) / 2;
|
||||
if (oem == p[i * 2]) break;
|
||||
if (oem > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
}
|
||||
}
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Unicode up-case conversion */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
DWORD ff_wtoupper ( /* Returns up-converted code point */
|
||||
DWORD uni /* Unicode code point to be up-converted */
|
||||
)
|
||||
{
|
||||
const WORD *p;
|
||||
WORD uc, bc, nc, cmd;
|
||||
static const WORD cvt1[] = { /* Compressed up conversion table for U+0000 - U+0FFF */
|
||||
/* Basic Latin */
|
||||
0x0061,0x031A,
|
||||
/* Latin-1 Supplement */
|
||||
0x00E0,0x0317,
|
||||
0x00F8,0x0307,
|
||||
0x00FF,0x0001,0x0178,
|
||||
/* Latin Extended-A */
|
||||
0x0100,0x0130,
|
||||
0x0132,0x0106,
|
||||
0x0139,0x0110,
|
||||
0x014A,0x012E,
|
||||
0x0179,0x0106,
|
||||
/* Latin Extended-B */
|
||||
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
|
||||
0x01CD,0x0110,
|
||||
0x01DD,0x0001,0x018E,
|
||||
0x01DE,0x0112,
|
||||
0x01F3,0x0003,0x01F1,0x01F4,0x01F4,
|
||||
0x01F8,0x0128,
|
||||
0x0222,0x0112,
|
||||
0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241,
|
||||
0x0246,0x010A,
|
||||
/* IPA Extensions */
|
||||
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
|
||||
/* Greek, Coptic */
|
||||
0x037B,0x0003,0x03FD,0x03FE,0x03FF,
|
||||
0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A,
|
||||
0x03B1,0x0311,
|
||||
0x03C2,0x0002,0x03A3,0x03A3,
|
||||
0x03C4,0x0308,
|
||||
0x03CC,0x0003,0x038C,0x038E,0x038F,
|
||||
0x03D8,0x0118,
|
||||
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
|
||||
/* Cyrillic */
|
||||
0x0430,0x0320,
|
||||
0x0450,0x0710,
|
||||
0x0460,0x0122,
|
||||
0x048A,0x0136,
|
||||
0x04C1,0x010E,
|
||||
0x04CF,0x0001,0x04C0,
|
||||
0x04D0,0x0144,
|
||||
/* Armenian */
|
||||
0x0561,0x0426,
|
||||
|
||||
0x0000 /* EOT */
|
||||
};
|
||||
static const WORD cvt2[] = { /* Compressed up conversion table for U+1000 - U+FFFF */
|
||||
/* Phonetic Extensions */
|
||||
0x1D7D,0x0001,0x2C63,
|
||||
/* Latin Extended Additional */
|
||||
0x1E00,0x0196,
|
||||
0x1EA0,0x015A,
|
||||
/* Greek Extended */
|
||||
0x1F00,0x0608,
|
||||
0x1F10,0x0606,
|
||||
0x1F20,0x0608,
|
||||
0x1F30,0x0608,
|
||||
0x1F40,0x0606,
|
||||
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F,
|
||||
0x1F60,0x0608,
|
||||
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
|
||||
0x1F80,0x0608,
|
||||
0x1F90,0x0608,
|
||||
0x1FA0,0x0608,
|
||||
0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
|
||||
0x1FCC,0x0001,0x1FC3,
|
||||
0x1FD0,0x0602,
|
||||
0x1FE0,0x0602,
|
||||
0x1FE5,0x0001,0x1FEC,
|
||||
0x1FF3,0x0001,0x1FFC,
|
||||
/* Letterlike Symbols */
|
||||
0x214E,0x0001,0x2132,
|
||||
/* Number forms */
|
||||
0x2170,0x0210,
|
||||
0x2184,0x0001,0x2183,
|
||||
/* Enclosed Alphanumerics */
|
||||
0x24D0,0x051A,
|
||||
0x2C30,0x042F,
|
||||
/* Latin Extended-C */
|
||||
0x2C60,0x0102,
|
||||
0x2C67,0x0106, 0x2C75,0x0102,
|
||||
/* Coptic */
|
||||
0x2C80,0x0164,
|
||||
/* Georgian Supplement */
|
||||
0x2D00,0x0826,
|
||||
/* Full-width */
|
||||
0xFF41,0x031A,
|
||||
|
||||
0x0000 /* EOT */
|
||||
};
|
||||
|
||||
|
||||
if (uni < 0x10000) { /* Is it in BMP? */
|
||||
uc = (WORD)uni;
|
||||
p = uc < 0x1000 ? cvt1 : cvt2;
|
||||
for (;;) {
|
||||
bc = *p++; /* Get the block base */
|
||||
if (bc == 0 || uc < bc) break; /* Not matched? */
|
||||
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
|
||||
if (uc < bc + nc) { /* In the block? */
|
||||
switch (cmd) {
|
||||
case 0: uc = p[uc - bc]; break; /* Table conversion */
|
||||
case 1: uc -= (uc - bc) & 1; break; /* Case pairs */
|
||||
case 2: uc -= 16; break; /* Shift -16 */
|
||||
case 3: uc -= 32; break; /* Shift -32 */
|
||||
case 4: uc -= 48; break; /* Shift -48 */
|
||||
case 5: uc -= 26; break; /* Shift -26 */
|
||||
case 6: uc += 8; break; /* Shift +8 */
|
||||
case 7: uc -= 80; break; /* Shift -80 */
|
||||
case 8: uc -= 0x1C60; break; /* Shift -0x1C60 */
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cmd == 0) p += nc; /* Skip table if needed */
|
||||
}
|
||||
uni = uc;
|
||||
}
|
||||
|
||||
return uni;
|
||||
}
|
||||
|
||||
|
||||
#endif /* #if FF_USE_LFN */
|
322
emummc/source/main.c
Normal file
322
emummc/source/main.c
Normal file
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "nx/svc.h"
|
||||
#include "nx/smc.h"
|
||||
#include "emuMMC/emummc.h"
|
||||
#include "emuMMC/emummc_ctx.h"
|
||||
#include "FS/FS_offsets.h"
|
||||
#include "utils/fatal.h"
|
||||
|
||||
// Prototypes
|
||||
void __init();
|
||||
void __initheap(void);
|
||||
void setup_hooks(void);
|
||||
void setup_nintendo_paths(void);
|
||||
void __libc_init_array(void);
|
||||
void hook_function(uintptr_t source, uintptr_t target);
|
||||
|
||||
void *__stack_top;
|
||||
uintptr_t text_base;
|
||||
char inner_heap[INNER_HEAP_SIZE];
|
||||
size_t inner_heap_size = INNER_HEAP_SIZE;
|
||||
extern char _start;
|
||||
extern char __injected_size__;
|
||||
|
||||
// Nintendo Path
|
||||
// TODO
|
||||
static char nintendo_path[0x80] = "Nintendo";
|
||||
|
||||
static char nintendo_path_album_100[0x100] = "/Nintendo/Album";
|
||||
static char nintendo_path_contents_100[0x100] = "/Nintendo/Contents";
|
||||
|
||||
// FS offsets
|
||||
static const fs_offsets_t *fs_offsets;
|
||||
|
||||
// Defined by linkerscript
|
||||
#define INJECTED_SIZE ((uintptr_t)&__injected_size__ - (uintptr_t)&_start)
|
||||
#define INJECT_OFFSET(type, offset) (type)(text_base + INJECTED_SIZE + offset)
|
||||
|
||||
#define GENERATE_ADD(register, register_target, value) (0x91000000 | value << 10 | register << 5 | register_target)
|
||||
#define GENERATE_ADRP(register, page_addr) (0x90000000 | ((((page_addr) >> 12) & 0x3) << 29) | ((((page_addr) >> 12) & 0x1FFFFC) << 3) | ((register) & 0x1F))
|
||||
#define GENERATE_BRANCH(source, destination) (0x14000000 | ((((destination) - (source)) >> 2) & 0x3FFFFFF))
|
||||
#define GENERATE_NOP() (0xD503201F)
|
||||
|
||||
#define INJECT_HOOK(offset, destination) hook_function(INJECT_OFFSET(uintptr_t, offset), (uintptr_t)&destination)
|
||||
#define INJECT_HOOK_RELATIVE(offset, relative_destination) hook_function(INJECT_OFFSET(uintptr_t, offset), INJECT_OFFSET(uintptr_t, offset) + relative_destination)
|
||||
#define INJECT_NOP(offset) write_nop(INJECT_OFFSET(uintptr_t, offset))
|
||||
|
||||
// emuMMC
|
||||
extern _sdmmc_accessor_gc sdmmc_accessor_gc;
|
||||
extern _sdmmc_accessor_sd sdmmc_accessor_sd;
|
||||
extern _sdmmc_accessor_nand sdmmc_accessor_nand;
|
||||
extern _lock_mutex lock_mutex;
|
||||
extern _unlock_mutex unlock_mutex;
|
||||
extern void *sd_mutex;
|
||||
extern void *nand_mutex;
|
||||
extern volatile int *active_partition;
|
||||
extern volatile Handle *sdmmc_das_handle;
|
||||
|
||||
// Storage
|
||||
volatile __attribute__((aligned(0x1000))) emuMMC_ctx_t emuMMC_ctx = {
|
||||
.magic = EMUMMC_STORAGE_MAGIC,
|
||||
.id = 0,
|
||||
.fs_ver = FS_VER_MAX,
|
||||
|
||||
// SD Default Metadata
|
||||
.SD_Type = emuMMC_SD,
|
||||
.SD_StoragePartitionOffset = 0,
|
||||
|
||||
// EMMC Default Metadata
|
||||
.EMMC_Type = emuMMC_EMMC,
|
||||
.EMMC_StoragePartitionOffset = 0,
|
||||
|
||||
// File Default Path
|
||||
.storagePath = "",
|
||||
};
|
||||
|
||||
// TODO: move into another file
|
||||
typedef struct
|
||||
{
|
||||
void *_0x0;
|
||||
void *_0x8;
|
||||
void *_0x10;
|
||||
void *_0x18;
|
||||
void *_0x20;
|
||||
void *_0x28;
|
||||
void *_0x30;
|
||||
void *_0x38;
|
||||
void *_0x40;
|
||||
Result (*set_min_v_clock_rate)(void *, uint32_t, uint32_t);
|
||||
} nn_clkrst_session_vt_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
nn_clkrst_session_vt_t *vt;
|
||||
} nn_clkrst_session_t;
|
||||
|
||||
Result clkrst_set_min_v_clock_rate(nn_clkrst_session_t **_this, uint32_t clk_rate)
|
||||
{
|
||||
Result rc = (*_this)->vt->set_min_v_clock_rate((void *)*_this, clk_rate, clk_rate);
|
||||
|
||||
if (rc == 0x6C0 || rc == 0)
|
||||
{ // TODO #define
|
||||
return 0;
|
||||
}
|
||||
if (rc != 0xAC0)
|
||||
{ // TODO #define
|
||||
fatal_abort(Fatal_BadResult);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void __initheap(void)
|
||||
{
|
||||
void *addr = inner_heap;
|
||||
size_t size = inner_heap_size;
|
||||
|
||||
/* Newlib Heap Management */
|
||||
extern char *fake_heap_start;
|
||||
extern char *fake_heap_end;
|
||||
|
||||
fake_heap_start = (char *)addr;
|
||||
fake_heap_end = (char *)addr + size;
|
||||
}
|
||||
|
||||
void hook_function(uintptr_t source, uintptr_t target)
|
||||
{
|
||||
u32 branch_opcode = GENERATE_BRANCH(source, target);
|
||||
smcWriteAddress32((void *)source, branch_opcode);
|
||||
}
|
||||
|
||||
void write_nop(uintptr_t source)
|
||||
{
|
||||
smcWriteAddress32((void *)source, GENERATE_NOP());
|
||||
}
|
||||
|
||||
void write_adrp_add(int reg, uintptr_t pc, intptr_t destination)
|
||||
{
|
||||
uintptr_t add_opcode_location = pc + sizeof(uint32_t);
|
||||
|
||||
intptr_t offset = (destination & 0xFFFFF000) - (pc & 0xFFFFF000);
|
||||
uint32_t opcode_adrp = GENERATE_ADRP(reg, offset);
|
||||
uint32_t opcode_add = GENERATE_ADD(reg, reg, (destination & 0x00000FFF));
|
||||
|
||||
// TODO: use 64 write?
|
||||
smcWriteAddress32((void *)pc, opcode_adrp);
|
||||
smcWriteAddress32((void *)add_opcode_location, opcode_add);
|
||||
}
|
||||
|
||||
void setup_hooks(void)
|
||||
{
|
||||
// rtld
|
||||
INJECT_HOOK_RELATIVE(fs_offsets->rtld, fs_offsets->rtld_destination);
|
||||
// sdmmc_wrapper_read hook
|
||||
INJECT_HOOK(fs_offsets->sdmmc_wrapper_read, sdmmc_wrapper_read);
|
||||
// sdmmc_wrapper_write hook
|
||||
INJECT_HOOK(fs_offsets->sdmmc_wrapper_write, sdmmc_wrapper_write);
|
||||
|
||||
// On 8.0.0+, we need to hook the regulator setup, because
|
||||
// otherwise it will abort because we have already turned it on.
|
||||
if (emuMMC_ctx.fs_ver >= FS_VER_8_0_0)
|
||||
{
|
||||
INJECT_HOOK(fs_offsets->clkrst_set_min_v_clock_rate, clkrst_set_min_v_clock_rate);
|
||||
}
|
||||
}
|
||||
|
||||
void populate_function_pointers(void)
|
||||
{
|
||||
// Accessor getters
|
||||
sdmmc_accessor_gc = INJECT_OFFSET(_sdmmc_accessor_gc, fs_offsets->sdmmc_accessor_gc);
|
||||
sdmmc_accessor_sd = INJECT_OFFSET(_sdmmc_accessor_sd, fs_offsets->sdmmc_accessor_sd);
|
||||
sdmmc_accessor_nand = INJECT_OFFSET(_sdmmc_accessor_nand, fs_offsets->sdmmc_accessor_nand);
|
||||
|
||||
// MutexLock functions
|
||||
lock_mutex = INJECT_OFFSET(_lock_mutex, fs_offsets->lock_mutex);
|
||||
unlock_mutex = INJECT_OFFSET(_unlock_mutex, fs_offsets->unlock_mutex);
|
||||
|
||||
// Other
|
||||
sd_mutex = INJECT_OFFSET(void *, fs_offsets->sd_mutex);
|
||||
nand_mutex = INJECT_OFFSET(void *, fs_offsets->nand_mutex);
|
||||
active_partition = INJECT_OFFSET(volatile int *, fs_offsets->active_partition);
|
||||
sdmmc_das_handle = INJECT_OFFSET(volatile Handle *, fs_offsets->sdmmc_das_handle);
|
||||
}
|
||||
|
||||
void write_nops(void)
|
||||
{
|
||||
// This NOPs out a call to ShutdownSdCard when preparing for shutdown/reboot.
|
||||
// This prevents the PatrolReader from hanging when saving its state, which
|
||||
// occurs immediately afterwards (in ShutdownMmc).
|
||||
INJECT_NOP(fs_offsets->shutdown_sd);
|
||||
// On 7.0.0+, we need to attach to device address space ourselves.
|
||||
// This patches an abort that happens when Nintendo's code sees SD
|
||||
// is already attached
|
||||
if (emuMMC_ctx.fs_ver >= FS_VER_7_0_0)
|
||||
{
|
||||
INJECT_NOP(fs_offsets->sd_das_init);
|
||||
}
|
||||
}
|
||||
|
||||
static void load_emummc_ctx(void)
|
||||
{
|
||||
exo_emummc_config_t config;
|
||||
static struct
|
||||
{
|
||||
char storage_path[sizeof(emuMMC_ctx.storagePath)];
|
||||
char nintendo_path[sizeof(nintendo_path)];
|
||||
} __attribute__((aligned(0x1000))) paths;
|
||||
|
||||
int x = smcGetEmummcConfig(EXO_EMUMMC_MMC_NAND, &config, &paths);
|
||||
if (x != 0)
|
||||
{
|
||||
fatal_abort(Fatal_GetConfig);
|
||||
}
|
||||
|
||||
if (config.base_cfg.magic == EMUMMC_STORAGE_MAGIC)
|
||||
{
|
||||
emuMMC_ctx.magic = config.base_cfg.magic;
|
||||
emuMMC_ctx.id = config.base_cfg.id;
|
||||
emuMMC_ctx.EMMC_Type = (enum emuMMC_Type)config.base_cfg.type;
|
||||
emuMMC_ctx.fs_ver = (enum FS_VER)config.base_cfg.fs_version;
|
||||
if (emuMMC_ctx.EMMC_Type == emuMMC_SD)
|
||||
{
|
||||
emuMMC_ctx.EMMC_StoragePartitionOffset = config.partition_cfg.start_sector;
|
||||
}
|
||||
else if (emuMMC_ctx.EMMC_Type == emuMMC_SD_File)
|
||||
{
|
||||
memcpy((void *)emuMMC_ctx.storagePath, paths.storage_path, sizeof(emuMMC_ctx.storagePath) - 1);
|
||||
emuMMC_ctx.storagePath[sizeof(emuMMC_ctx.storagePath) - 1] = 0;
|
||||
}
|
||||
memcpy(nintendo_path, paths.nintendo_path, sizeof(nintendo_path) - 1);
|
||||
nintendo_path[sizeof(nintendo_path) - 1] = 0;
|
||||
if (strcmp(nintendo_path, "") == 0)
|
||||
{
|
||||
snprintf(nintendo_path, sizeof(nintendo_path), "emummc/Nintendo_%04x", emuMMC_ctx.id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal_abort(Fatal_GetConfig);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_nintendo_paths(void)
|
||||
{
|
||||
if (emuMMC_ctx.fs_ver > FS_VER_1_0_0)
|
||||
{
|
||||
for (int i = 0; fs_offsets->nintendo_paths[i].adrp_offset; i++)
|
||||
{
|
||||
intptr_t nintendo_path_location = (intptr_t)&nintendo_path;
|
||||
uintptr_t fs_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[i].adrp_offset);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[i].opcode_reg, fs_adrp_opcode_location, nintendo_path_location);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 1.0.0 needs special handling because it uses two paths.
|
||||
// Do album path
|
||||
{
|
||||
int path_len = snprintf(nintendo_path_album_100, sizeof(nintendo_path_album_100), "/%s/Album", nintendo_path);
|
||||
intptr_t nintendo_album_path_location = (intptr_t)&nintendo_path_album_100;
|
||||
intptr_t album_path_location = nintendo_album_path_location + path_len - 6; // "/Album"
|
||||
uintptr_t fs_n_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[0].adrp_offset);
|
||||
uintptr_t fs_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[1].adrp_offset);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[0].opcode_reg, fs_n_adrp_opcode_location, nintendo_album_path_location);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[1].opcode_reg, fs_adrp_opcode_location, album_path_location);
|
||||
}
|
||||
// Do contents path
|
||||
{
|
||||
int path_len = snprintf(nintendo_path_contents_100, sizeof(nintendo_path_contents_100), "/%s/Contents", nintendo_path);
|
||||
intptr_t nintendo_contents_path_location = (intptr_t)&nintendo_path_contents_100;
|
||||
intptr_t contents_path_location = nintendo_contents_path_location + path_len - 9; // "/Contents"
|
||||
uintptr_t fs_n_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[2].adrp_offset);
|
||||
uintptr_t fs_adrp_opcode_location = INJECT_OFFSET(uintptr_t, fs_offsets->nintendo_paths[3].adrp_offset);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[2].opcode_reg, fs_n_adrp_opcode_location, nintendo_contents_path_location);
|
||||
write_adrp_add(fs_offsets->nintendo_paths[3].opcode_reg, fs_adrp_opcode_location, contents_path_location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// inject main func
|
||||
void __init()
|
||||
{
|
||||
// Call constructors.
|
||||
__libc_init_array();
|
||||
|
||||
MemoryInfo meminfo;
|
||||
u32 pageinfo;
|
||||
svcQueryMemory(&meminfo, &pageinfo, (u64)&_start);
|
||||
|
||||
text_base = meminfo.addr;
|
||||
|
||||
load_emummc_ctx();
|
||||
|
||||
fs_offsets = get_fs_offsets(emuMMC_ctx.fs_ver);
|
||||
|
||||
setup_hooks();
|
||||
populate_function_pointers();
|
||||
write_nops();
|
||||
setup_nintendo_paths();
|
||||
|
||||
sdmmc_initialize();
|
||||
}
|
41
emummc/source/nx/cache.h
Normal file
41
emummc/source/nx/cache.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @file cache.h
|
||||
* @brief AArch64 cache operations.
|
||||
* @author plutoo
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
#pragma once
|
||||
#include "../utils/types.h"
|
||||
|
||||
/**
|
||||
* @brief Performs a data cache flush on the specified buffer.
|
||||
* @param addr Address of the buffer.
|
||||
* @param size Size of the buffer, in bytes.
|
||||
* @remarks Cache flush is defined as Clean + Invalidate.
|
||||
* @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register).
|
||||
*/
|
||||
void armDCacheFlush(void* addr, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Performs a data cache clean on the specified buffer.
|
||||
* @param addr Address of the buffer.
|
||||
* @param size Size of the buffer, in bytes.
|
||||
* @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register).
|
||||
*/
|
||||
void armDCacheClean(void* addr, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Performs an instruction cache invalidation clean on the specified buffer.
|
||||
* @param addr Address of the buffer.
|
||||
* @param size Size of the buffer, in bytes.
|
||||
* @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register).
|
||||
*/
|
||||
void armICacheInvalidate(void* addr, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Performs a data cache zeroing operation on the specified buffer.
|
||||
* @param addr Address of the buffer.
|
||||
* @param size Size of the buffer, in bytes.
|
||||
* @note The start and end addresses of the buffer are forcibly rounded to cache line boundaries (read from CTR_EL0 system register).
|
||||
*/
|
||||
void armDCacheZero(void* addr, size_t size);
|
100
emummc/source/nx/cache.s
Normal file
100
emummc/source/nx/cache.s
Normal file
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* @file cache.s
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
|
||||
.macro CODE_BEGIN name
|
||||
.section .text.\name, "ax", %progbits
|
||||
.global \name
|
||||
.type \name, %function
|
||||
.align 2
|
||||
.cfi_startproc
|
||||
\name:
|
||||
.endm
|
||||
|
||||
.macro CODE_END
|
||||
.cfi_endproc
|
||||
.endm
|
||||
|
||||
CODE_BEGIN armDCacheFlush
|
||||
add x1, x1, x0
|
||||
mrs x8, CTR_EL0
|
||||
lsr x8, x8, #16
|
||||
and x8, x8, #0xf
|
||||
mov x9, #4
|
||||
lsl x9, x9, x8
|
||||
sub x10, x9, #1
|
||||
bic x8, x0, x10
|
||||
mov x10, x1
|
||||
|
||||
armDCacheFlush_L0:
|
||||
dc civac, x8
|
||||
add x8, x8, x9
|
||||
cmp x8, x10
|
||||
bcc armDCacheFlush_L0
|
||||
|
||||
dsb sy
|
||||
ret
|
||||
CODE_END
|
||||
|
||||
CODE_BEGIN armDCacheClean
|
||||
add x1, x1, x0
|
||||
mrs x8, CTR_EL0
|
||||
lsr x8, x8, #16
|
||||
and x8, x8, #0xf
|
||||
mov x9, #4
|
||||
lsl x9, x9, x8
|
||||
sub x10, x9, #1
|
||||
bic x8, x0, x10
|
||||
mov x10, x1
|
||||
|
||||
armDCacheClean_L0:
|
||||
dc cvac, x8
|
||||
add x8, x8, x9
|
||||
cmp x8, x10
|
||||
bcc armDCacheClean_L0
|
||||
|
||||
dsb sy
|
||||
ret
|
||||
CODE_END
|
||||
|
||||
CODE_BEGIN armICacheInvalidate
|
||||
add x1, x1, x0
|
||||
mrs x8, CTR_EL0
|
||||
and x8, x8, #0xf
|
||||
mov x9, #4
|
||||
lsl x9, x9, x8
|
||||
sub x10, x9, #1
|
||||
bic x8, x0, x10
|
||||
mov x10, x1
|
||||
|
||||
armICacheInvalidate_L0:
|
||||
ic ivau, x8
|
||||
add x8, x8, x9
|
||||
cmp x8, x10
|
||||
bcc armICacheInvalidate_L0
|
||||
|
||||
dsb sy
|
||||
ret
|
||||
CODE_END
|
||||
|
||||
CODE_BEGIN armDCacheZero
|
||||
add x1, x1, x0
|
||||
mrs x8, CTR_EL0
|
||||
lsr x8, x8, #16
|
||||
and x8, x8, #0xf
|
||||
mov x9, #4
|
||||
lsl x9, x9, x8
|
||||
sub x10, x9, #1
|
||||
bic x8, x0, x10
|
||||
mov x10, x1
|
||||
|
||||
armDCacheZero_L0:
|
||||
dc zva, x8
|
||||
add x8, x8, x9
|
||||
cmp x8, x10
|
||||
bcc armDCacheZero_L0
|
||||
|
||||
dsb sy
|
||||
ret
|
||||
CODE_END
|
46
emummc/source/nx/counter.h
Normal file
46
emummc/source/nx/counter.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* @file counter.h
|
||||
* @brief AArch64 system counter-timer.
|
||||
* @author fincs
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
#pragma once
|
||||
#include "../utils/types.h"
|
||||
|
||||
/**
|
||||
* @brief Gets the current system tick.
|
||||
* @return The current system tick.
|
||||
*/
|
||||
static inline u64 armGetSystemTick(void) {
|
||||
u64 ret;
|
||||
__asm__ __volatile__ ("mrs %x[data], cntpct_el0" : [data] "=r" (ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the system counter-timer frequency
|
||||
* @return The system counter-timer frequency, in Hz.
|
||||
*/
|
||||
static inline u64 armGetSystemTickFreq(void) {
|
||||
u64 ret;
|
||||
__asm__ ("mrs %x[data], cntfrq_el0" : [data] "=r" (ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts from nanoseconds to CPU ticks unit.
|
||||
* @param ns Time in nanoseconds.
|
||||
* @return Time in CPU ticks.
|
||||
*/
|
||||
static inline u64 armNsToTicks(u64 ns) {
|
||||
return (ns * 12) / 625;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts from CPU ticks unit to nanoseconds.
|
||||
* @param tick Time in ticks.
|
||||
* @return Time in nanoseconds.
|
||||
*/
|
||||
static inline u64 armTicksToNs(u64 tick) {
|
||||
return (tick * 625) / 12;
|
||||
}
|
45
emummc/source/nx/dynamic.c
Normal file
45
emummc/source/nx/dynamic.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* @file dynamic.c
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../utils/types.h"
|
||||
#include <elf.h>
|
||||
|
||||
void __nx_dynamic(uintptr_t base, const Elf64_Dyn* dyn)
|
||||
{
|
||||
const Elf64_Rela* rela = NULL;
|
||||
u64 relasz = 0;
|
||||
|
||||
for (; dyn->d_tag != DT_NULL; dyn++)
|
||||
{
|
||||
switch (dyn->d_tag)
|
||||
{
|
||||
case DT_RELA:
|
||||
rela = (const Elf64_Rela*)(base + dyn->d_un.d_ptr);
|
||||
break;
|
||||
case DT_RELASZ:
|
||||
relasz = dyn->d_un.d_val / sizeof(Elf64_Rela);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rela == NULL) {
|
||||
while(true)
|
||||
;
|
||||
}
|
||||
|
||||
for (; relasz--; rela++)
|
||||
{
|
||||
switch (ELF64_R_TYPE(rela->r_info))
|
||||
{
|
||||
case R_AARCH64_RELATIVE:
|
||||
{
|
||||
u64* ptr = (u64*)(base + rela->r_offset);
|
||||
*ptr = base + rela->r_addend;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3147
emummc/source/nx/elf.h
Normal file
3147
emummc/source/nx/elf.h
Normal file
File diff suppressed because it is too large
Load diff
180
emummc/source/nx/smc.c
Normal file
180
emummc/source/nx/smc.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
* @file smc.c
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "smc.h"
|
||||
|
||||
void smcRebootToRcm(void)
|
||||
{
|
||||
SecmonArgs args;
|
||||
args.X[0] = 0xC3000401; /* smcSetConfig */
|
||||
args.X[1] = SplConfigItem_NeedsReboot; /* Exosphere reboot */
|
||||
args.X[3] = 1; /* Perform reboot to RCM. */
|
||||
svcCallSecureMonitor(&args);
|
||||
}
|
||||
|
||||
void smcRebootToIramPayload(void)
|
||||
{
|
||||
SecmonArgs args;
|
||||
args.X[0] = 0xC3000401; /* smcSetConfig */
|
||||
args.X[1] = SplConfigItem_NeedsReboot; /* Exosphere reboot */
|
||||
args.X[3] = 2; /* Perform reboot to payload at 0x40010000 in IRAM. */
|
||||
svcCallSecureMonitor(&args);
|
||||
}
|
||||
|
||||
void smcPerformShutdown(void)
|
||||
{
|
||||
SecmonArgs args;
|
||||
args.X[0] = 0xC3000401; /* smcSetConfig */
|
||||
args.X[1] = SplConfigItem_NeedsShutdown; /* Exosphere shutdown */
|
||||
args.X[3] = 1; /* Perform shutdown. */
|
||||
svcCallSecureMonitor(&args);
|
||||
}
|
||||
|
||||
Result smcGetConfig(SplConfigItem config_item, u64 *out_config)
|
||||
{
|
||||
SecmonArgs args;
|
||||
args.X[0] = 0xC3000002; /* smcGetConfig */
|
||||
args.X[1] = (u64)config_item; /* config item */
|
||||
Result rc = svcCallSecureMonitor(&args);
|
||||
if (rc == 0)
|
||||
{
|
||||
if (args.X[0] == 0)
|
||||
{
|
||||
if (out_config)
|
||||
{
|
||||
*out_config = args.X[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SPL result n = SMC result n */
|
||||
rc = (26u | ((u32)args.X[0] << 9u));
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result smcCopyToIram(uintptr_t iram_addr, const void *src_addr, u32 size)
|
||||
{
|
||||
SecmonArgs args;
|
||||
args.X[0] = 0xF0000201; /* smcAmsIramCopy */
|
||||
args.X[1] = (u64)src_addr; /* DRAM address */
|
||||
args.X[2] = (u64)iram_addr; /* IRAM address */
|
||||
args.X[3] = size; /* Amount to copy */
|
||||
args.X[4] = 1; /* 1 = Write */
|
||||
Result rc = svcCallSecureMonitor(&args);
|
||||
if (rc == 0)
|
||||
{
|
||||
if (args.X[0] != 0)
|
||||
{
|
||||
/* SPL result n = SMC result n */
|
||||
rc = (26u | ((u32)args.X[0] << 9u));
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result smcCopyFromIram(void *dst_addr, uintptr_t iram_addr, u32 size)
|
||||
{
|
||||
SecmonArgs args;
|
||||
args.X[0] = 0xF0000201; /* smcAmsIramCopy */
|
||||
args.X[1] = (u64)dst_addr; /* DRAM address */
|
||||
args.X[2] = (u64)iram_addr; /* IRAM address */
|
||||
args.X[3] = size; /* Amount to copy */
|
||||
args.X[4] = 0; /* 0 = Read */
|
||||
Result rc = svcCallSecureMonitor(&args);
|
||||
if (rc == 0)
|
||||
{
|
||||
if (args.X[0] != 0)
|
||||
{
|
||||
/* SPL result n = SMC result n */
|
||||
rc = (26u | ((u32)args.X[0] << 9u));
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result smcReadWriteRegister(u32 phys_addr, u32 value, u32 mask)
|
||||
{
|
||||
SecmonArgs args;
|
||||
args.X[0] = 0xF0000002; /* smcAmsReadWriteRegister */
|
||||
args.X[1] = phys_addr; /* MMIO address */
|
||||
args.X[2] = mask; /* mask */
|
||||
args.X[3] = value; /* value */
|
||||
Result rc = svcCallSecureMonitor(&args);
|
||||
if (rc == 0)
|
||||
{
|
||||
if (args.X[0] != 0)
|
||||
{
|
||||
/* SPL result n = SMC result n */
|
||||
rc = (26u | ((u32)args.X[0] << 9u));
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _smcWriteAddress(void *dst_addr, u64 val, u32 size)
|
||||
{
|
||||
SecmonArgs args;
|
||||
args.X[0] = 0xF0000003; /* smcAmsWriteAddress */
|
||||
args.X[1] = (u64)dst_addr; /* DRAM address */
|
||||
args.X[2] = val; /* value */
|
||||
args.X[3] = size; /* Amount to write */
|
||||
Result rc = svcCallSecureMonitor(&args);
|
||||
if (rc == 0)
|
||||
{
|
||||
if (args.X[0] != 0)
|
||||
{
|
||||
/* SPL result n = SMC result n */
|
||||
rc = (26u | ((u32)args.X[0] << 9u));
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result smcWriteAddress8(void *dst_addr, u8 val)
|
||||
{
|
||||
return _smcWriteAddress(dst_addr, val, 1);
|
||||
}
|
||||
|
||||
Result smcWriteAddress16(void *dst_addr, u16 val)
|
||||
{
|
||||
return _smcWriteAddress(dst_addr, val, 2);
|
||||
}
|
||||
|
||||
Result smcWriteAddress32(void *dst_addr, u32 val)
|
||||
{
|
||||
return _smcWriteAddress(dst_addr, val, 4);
|
||||
}
|
||||
|
||||
Result smcWriteAddress64(void *dst_addr, u64 val)
|
||||
{
|
||||
return _smcWriteAddress(dst_addr, val, 8);
|
||||
}
|
||||
|
||||
Result smcGetEmummcConfig(exo_emummc_mmc_t mmc_id, exo_emummc_config_t *out_cfg, void *out_paths)
|
||||
{
|
||||
SecmonArgs args;
|
||||
args.X[0] = 0xF0000404; /* smcAmsGetEmunandConfig */
|
||||
args.X[1] = mmc_id;
|
||||
args.X[2] = (u64)out_paths; /* out path */
|
||||
Result rc = svcCallSecureMonitor(&args);
|
||||
if (rc == 0)
|
||||
{
|
||||
if (args.X[0] != 0)
|
||||
{
|
||||
/* SPL result n = SMC result n */
|
||||
rc = (26u | ((u32)args.X[0] << 9u));
|
||||
}
|
||||
if (rc == 0)
|
||||
{
|
||||
memcpy(out_cfg, &args.X[1], sizeof(*out_cfg));
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
||||
}
|
90
emummc/source/nx/smc.h
Normal file
90
emummc/source/nx/smc.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* @file smc.h
|
||||
* @brief Wrappers for secure monitor calls.
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
#pragma once
|
||||
#include "../utils/types.h"
|
||||
#include "svc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
SplConfigItem_DisableProgramVerification = 1,
|
||||
SplConfigItem_DramId = 2,
|
||||
SplConfigItem_SecurityEngineIrqNumber = 3,
|
||||
SplConfigItem_Version = 4,
|
||||
SplConfigItem_HardwareType = 5,
|
||||
SplConfigItem_IsRetail = 6,
|
||||
SplConfigItem_IsRecoveryBoot = 7,
|
||||
SplConfigItem_DeviceId = 8,
|
||||
SplConfigItem_BootReason = 9,
|
||||
SplConfigItem_MemoryArrange = 10,
|
||||
SplConfigItem_IsDebugMode = 11,
|
||||
SplConfigItem_KernelMemoryConfiguration = 12,
|
||||
SplConfigItem_IsChargerHiZModeEnabled = 13,
|
||||
SplConfigItem_IsKiosk = 14,
|
||||
SplConfigItem_NewHardwareType = 15,
|
||||
SplConfigItem_NewKeyGeneration = 16,
|
||||
SplConfigItem_Package2Hash = 17,
|
||||
|
||||
SplConfigItem_ExosphereVersion = 65000,
|
||||
SplConfigItem_NeedsReboot = 65001,
|
||||
SplConfigItem_NeedsShutdown = 65002,
|
||||
SplConfigItem_ExosphereVerHash = 65003,
|
||||
SplConfigItem_HasRcmBugPatch = 65004,
|
||||
} SplConfigItem;
|
||||
|
||||
typedef enum {
|
||||
EXO_EMUMMC_TYPE_NONE = 0,
|
||||
EXO_EMUMMC_TYPE_PARTITION = 1,
|
||||
EXO_EMUMMC_TYPE_FILES = 2,
|
||||
} exo_emummc_type_t;
|
||||
|
||||
typedef enum {
|
||||
EXO_EMUMMC_MMC_NAND = 0,
|
||||
EXO_EMUMMC_MMC_SD = 1,
|
||||
EXO_EMUMMC_MMC_GC = 2,
|
||||
} exo_emummc_mmc_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
uint32_t type;
|
||||
uint32_t id;
|
||||
uint32_t fs_version;
|
||||
} exo_emummc_base_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t start_sector;
|
||||
} exo_emummc_partition_config_t;
|
||||
|
||||
typedef struct {
|
||||
exo_emummc_base_config_t base_cfg;
|
||||
union {
|
||||
exo_emummc_partition_config_t partition_cfg;
|
||||
};
|
||||
} exo_emummc_config_t;
|
||||
|
||||
Result smcGetConfig(SplConfigItem config_item, u64 *out_config);
|
||||
|
||||
void smcRebootToRcm(void);
|
||||
void smcRebootToIramPayload(void);
|
||||
void smcPerformShutdown(void);
|
||||
|
||||
Result smcCopyToIram(uintptr_t iram_addr, const void *src_addr, u32 size);
|
||||
Result smcCopyFromIram(void *dst_addr, uintptr_t iram_addr, u32 size);
|
||||
|
||||
Result smcReadWriteRegister(u32 phys_addr, u32 value, u32 mask);
|
||||
|
||||
Result smcWriteAddress8(void *dst_addr, u8 val);
|
||||
Result smcWriteAddress16(void *dst_addr, u16 val);
|
||||
Result smcWriteAddress32(void *dst_addr, u32 val);
|
||||
Result smcWriteAddress64(void *dst_addr, u64 val);
|
||||
|
||||
Result smcGetEmummcConfig(exo_emummc_mmc_t mmc_id, exo_emummc_config_t *out_cfg, void *out_paths);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
131
emummc/source/nx/start.s
Normal file
131
emummc/source/nx/start.s
Normal file
|
@ -0,0 +1,131 @@
|
|||
/**
|
||||
* @file start.s
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
|
||||
.macro push_all
|
||||
SUB SP, SP, #0x100
|
||||
STP X29, X30, [SP, #0x0]
|
||||
STP X27, X28, [SP, #0x10]
|
||||
STP X25, X26, [SP, #0x20]
|
||||
STP X23, X24, [SP, #0x30]
|
||||
STP X21, X22, [SP, #0x40]
|
||||
STP X19, X20, [SP, #0x50]
|
||||
STP X17, X18, [SP, #0x60]
|
||||
STP X15, X16, [SP, #0x70]
|
||||
STP X13, X14, [SP, #0x80]
|
||||
STP X11, X12, [SP, #0x90]
|
||||
STP X9, X10, [SP, #0xA0]
|
||||
STP X7, X8, [SP, #0xB0]
|
||||
STP X5, X6, [SP, #0xC0]
|
||||
STP X3, X4, [SP, #0xD0]
|
||||
STP X1, X2, [SP, #0xE0]
|
||||
STR X0, [SP, #0xF0]
|
||||
.endm
|
||||
|
||||
.macro pop_all
|
||||
LDR X0, [SP, #0xF0]
|
||||
LDP X1, X2, [SP, #0xE0]
|
||||
LDP X3, X4, [SP, #0xD0]
|
||||
LDP X5, X6, [SP, #0xC0]
|
||||
LDP X7, X8, [SP, #0xB0]
|
||||
LDP X9, X10, [SP, #0xA0]
|
||||
LDP X11, X12, [SP, #0x90]
|
||||
LDP X13, X14, [SP, #0x80]
|
||||
LDP X15, X16, [SP, #0x70]
|
||||
LDP X17, X18, [SP, #0x60]
|
||||
LDP X19, X20, [SP, #0x50]
|
||||
LDP X21, X22, [SP, #0x40]
|
||||
LDP X23, X24, [SP, #0x30]
|
||||
LDP X25, X26, [SP, #0x20]
|
||||
LDP X27, X28, [SP, #0x10]
|
||||
LDP X29, X30, [SP, #0x0]
|
||||
ADD SP, SP, #0x100
|
||||
.endm
|
||||
|
||||
.section ".crt0","ax"
|
||||
.global _start
|
||||
_start:
|
||||
B startup
|
||||
.org _start+0xc
|
||||
B sdmmc_wrapper_read
|
||||
.org _start+0x18
|
||||
B sdmmc_wrapper_write
|
||||
.org _start+0x80
|
||||
|
||||
.section ".crt0","ax"
|
||||
startup:
|
||||
# Save LR
|
||||
MOV X7, X30
|
||||
|
||||
# Retrieve ASLR Base
|
||||
BL +4
|
||||
SUB X6, X30, #0x88
|
||||
|
||||
# Context Ptr and MainThread Handle
|
||||
MOV X5, X0
|
||||
MOV X4, X1
|
||||
|
||||
# Inject start
|
||||
push_all
|
||||
|
||||
MOV W0, #0xFFFF8001
|
||||
ADR X1, __rodata_start
|
||||
ADR X2, __data_start
|
||||
SUB X2, X2, X1
|
||||
MOV X3, #1
|
||||
SVC 0x73
|
||||
|
||||
MOV W0, #0xFFFF8001
|
||||
ADR X1, __data_start
|
||||
ADR X2, __end__
|
||||
SUB X2, X2, X1
|
||||
MOV X3, #3
|
||||
SVC 0x73
|
||||
|
||||
pop_all
|
||||
|
||||
MOV X27, X7
|
||||
MOV X25, X5
|
||||
MOV X26, X4
|
||||
|
||||
# Clear .bss
|
||||
ADRP X0, __bss_start__
|
||||
ADRP X1, __bss_end__
|
||||
ADD X0, X0, #:lo12:__bss_start__
|
||||
ADD X1, X1, #:lo12:__bss_end__
|
||||
SUB X1, X1, X0
|
||||
ADD X1, X1, #7
|
||||
BIC X1, X1, #7
|
||||
|
||||
bss_loop:
|
||||
STR XZR, [X0], #8
|
||||
SUBS X1, X1, #8
|
||||
BNE bss_loop
|
||||
|
||||
# Store SP
|
||||
MOV X1, SP
|
||||
ADRP X0, __stack_top
|
||||
STR X1, [X0, #:lo12:__stack_top]
|
||||
|
||||
# Process _DYNAMIC Section
|
||||
MOV X0, X6
|
||||
ADRP X1, _DYNAMIC
|
||||
ADD X1, X1, #:lo12:_DYNAMIC
|
||||
BL __nx_dynamic
|
||||
|
||||
# TODO: handle in code
|
||||
MOV X0, X25
|
||||
MOV X1, X26
|
||||
MOV X2, X27
|
||||
|
||||
BL __initheap
|
||||
BL __init
|
||||
|
||||
MOV X0, X25
|
||||
MOV X1, X26
|
||||
MOV X30, X27
|
||||
|
||||
# FS main
|
||||
ADR X16, __injected_size__
|
||||
BR X16
|
112
emummc/source/nx/svc.h
Normal file
112
emummc/source/nx/svc.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
* @file svc.h
|
||||
* @brief Wrappers for kernel syscalls.
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
#pragma once
|
||||
#include "../utils/types.h"
|
||||
|
||||
/// Memory information structure.
|
||||
typedef struct {
|
||||
u64 addr; ///< Base address.
|
||||
u64 size; ///< Size.
|
||||
u32 type; ///< Memory type (see lower 8 bits of \ref MemoryState).
|
||||
u32 attr; ///< Memory attributes (see \ref MemoryAttribute).
|
||||
u32 perm; ///< Memory permissions (see \ref Permission).
|
||||
u32 device_refcount; ///< Device reference count.
|
||||
u32 ipc_refcount; ///< IPC reference count.
|
||||
u32 padding; ///< Padding.
|
||||
} MemoryInfo;
|
||||
|
||||
/// Memory permission bitmasks.
|
||||
typedef enum {
|
||||
Perm_None = 0, ///< No permissions.
|
||||
Perm_R = BIT(0), ///< Read permission.
|
||||
Perm_W = BIT(1), ///< Write permission.
|
||||
Perm_X = BIT(2), ///< Execute permission.
|
||||
Perm_Rw = Perm_R | Perm_W, ///< Read/write permissions.
|
||||
Perm_Rx = Perm_R | Perm_X, ///< Read/execute permissions.
|
||||
Perm_DontCare = BIT(28), ///< Don't care
|
||||
} Permission;
|
||||
|
||||
/// Secure monitor arguments.
|
||||
typedef struct {
|
||||
u64 X[8]; ///< Values of X0 through X7.
|
||||
} SecmonArgs;
|
||||
|
||||
_Static_assert(sizeof(SecmonArgs) == 0x40, "SecmonArgs definition");
|
||||
|
||||
#define DeviceName_SDMMC1A 19
|
||||
#define DeviceName_SDMMC2A 20
|
||||
#define DeviceName_SDMMC3A 21
|
||||
#define DeviceName_SDMMC4A 22
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Returns a virtual address mapped to a given IO range.
|
||||
* @return Result code.
|
||||
* @note Syscall number 0x55.
|
||||
* @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available.
|
||||
*/
|
||||
Result svcQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size);
|
||||
|
||||
/**
|
||||
* @brief Attaches a device address space to a device.
|
||||
* @return Result code.
|
||||
* @note Syscall number 0x57.
|
||||
* @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available.
|
||||
*/
|
||||
Result svcAttachDeviceAddressSpace(u64 device, Handle handle);
|
||||
|
||||
/**
|
||||
* @brief Query information about an address. Will always fetch the lowest page-aligned mapping that contains the provided address.
|
||||
* @param[out] meminfo_ptr \ref MemoryInfo structure which will be filled in.
|
||||
* @param[out] pageinfo Page information which will be filled in.
|
||||
* @param[in] addr Address to query.
|
||||
* @return Result code.
|
||||
* @note Syscall number 0x06.
|
||||
*/
|
||||
Result svcQueryMemory(MemoryInfo* meminfo_ptr, u32 *pageinfo, u64 addr);
|
||||
|
||||
/**
|
||||
* @brief Sets the memory permissions for the specified memory with the supplied process handle.
|
||||
* @param[in] proc Process handle.
|
||||
* @param[in] addr Address of the memory.
|
||||
* @param[in] size Size of the memory.
|
||||
* @param[in] perm Permissions (see \ref Permission).
|
||||
* @return Result code.
|
||||
* @remark This returns an error (0xD801) when \p perm is >0x5, hence -WX and RWX are not allowed.
|
||||
* @note Syscall number 0x73.
|
||||
* @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available.
|
||||
*/
|
||||
Result svcSetProcessMemoryPermission(Handle proc, u64 addr, u64 size, u32 perm);
|
||||
|
||||
/**
|
||||
* @brief Set the memory permissions of a (page-aligned) range of memory.
|
||||
* @param[in] addr Start address of the range.
|
||||
* @param[in] size Size of the range, in bytes.
|
||||
* @param[in] perm Permissions (see \ref Permission).
|
||||
* @return Result code.
|
||||
* @remark Perm_X is not allowed. Setting write-only is not allowed either (Perm_W).
|
||||
* This can be used to move back and forth between Perm_None, Perm_R and Perm_Rw.
|
||||
* @note Syscall number 0x01.
|
||||
*/
|
||||
Result svcSetMemoryPermission(void* addr, u64 size, u32 perm);
|
||||
|
||||
/**
|
||||
* @brief Calls a secure monitor function (TrustZone, EL3).
|
||||
* @param regs Arguments to pass to the secure monitor.
|
||||
* @return Return value from the secure monitor.
|
||||
* @note Syscall number 0x7F.
|
||||
* @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available.
|
||||
*/
|
||||
u64 svcCallSecureMonitor(SecmonArgs* regs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
///@}
|
64
emummc/source/nx/svc.s
Normal file
64
emummc/source/nx/svc.s
Normal file
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* @file svc.s
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
|
||||
.macro SVC_BEGIN name
|
||||
.section .text.\name, "ax", %progbits
|
||||
.global \name
|
||||
.type \name, %function
|
||||
.align 2
|
||||
.cfi_startproc
|
||||
\name:
|
||||
.endm
|
||||
|
||||
.macro SVC_END
|
||||
.cfi_endproc
|
||||
.endm
|
||||
|
||||
SVC_BEGIN svcQueryIoMapping
|
||||
STR X0, [SP, #-16]!
|
||||
SVC 0x55
|
||||
LDR X2, [SP], #16
|
||||
STR X1, [X2]
|
||||
RET
|
||||
SVC_END
|
||||
|
||||
SVC_BEGIN svcAttachDeviceAddressSpace
|
||||
SVC 0x57
|
||||
RET
|
||||
SVC_END
|
||||
|
||||
SVC_BEGIN svcQueryMemory
|
||||
STR X1, [SP, #-16]!
|
||||
SVC 0x6
|
||||
LDR X2, [SP], #16
|
||||
STR W1, [X2]
|
||||
RET
|
||||
SVC_END
|
||||
|
||||
SVC_BEGIN svcSetMemoryPermission
|
||||
SVC 0x2
|
||||
RET
|
||||
SVC_END
|
||||
|
||||
SVC_BEGIN svcSetProcessMemoryPermission
|
||||
SVC 0x73
|
||||
RET
|
||||
SVC_END
|
||||
|
||||
SVC_BEGIN svcCallSecureMonitor
|
||||
STR X0, [SP, #-16]!
|
||||
MOV X8, X0
|
||||
LDP X0, X1, [X8]
|
||||
LDP X2, X3, [X8, #0x10]
|
||||
LDP X4, X5, [X8, #0x20]
|
||||
LDP X6, X7, [X8, #0x30]
|
||||
SVC 0x7F
|
||||
LDR X8, [SP], #16
|
||||
STP X0, X1, [X8]
|
||||
STP X2, X3, [X8, #0x10]
|
||||
STP X4, X5, [X8, #0x20]
|
||||
STP X6, X7, [X8, #0x30]
|
||||
RET
|
||||
SVC_END
|
331
emummc/source/power/max77620.h
Normal file
331
emummc/source/power/max77620.h
Normal file
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
* Defining registers address and its bit definitions of MAX77620 and MAX20024
|
||||
*
|
||||
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _MFD_MAX77620_H_
|
||||
#define _MFD_MAX77620_H_
|
||||
|
||||
#define MAX77620_I2C_ADDR 0x3C
|
||||
|
||||
/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */
|
||||
#define MAX77620_REG_CNFGGLBL1 0x00
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7)
|
||||
#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
|
||||
#define MAX77620_CNFGGLBL1_LBHYST_N (1 << 4)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC 0x0E
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_N (1 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0)
|
||||
|
||||
#define MAX77620_REG_CNFGGLBL2 0x01
|
||||
#define MAX77620_REG_CNFGGLBL3 0x02
|
||||
#define MAX77620_WDTC_MASK 0x3
|
||||
#define MAX77620_WDTOFFC (1 << 4)
|
||||
#define MAX77620_WDTSLPC (1 << 3)
|
||||
#define MAX77620_WDTEN (1 << 2)
|
||||
#define MAX77620_TWD_MASK 0x3
|
||||
#define MAX77620_TWD_2s 0x0
|
||||
#define MAX77620_TWD_16s 0x1
|
||||
#define MAX77620_TWD_64s 0x2
|
||||
#define MAX77620_TWD_128s 0x3
|
||||
|
||||
#define MAX77620_REG_CNFG1_32K 0x03
|
||||
#define MAX77620_CNFG1_32K_OUT0_EN (1 << 2)
|
||||
|
||||
#define MAX77620_REG_CNFGBBC 0x04
|
||||
#define MAX77620_CNFGBBC_ENABLE (1 << 0)
|
||||
#define MAX77620_CNFGBBC_CURRENT_MASK 0x06
|
||||
#define MAX77620_CNFGBBC_CURRENT_SHIFT 1
|
||||
#define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18
|
||||
#define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3
|
||||
#define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE (1 << 5)
|
||||
#define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0
|
||||
#define MAX77620_CNFGBBC_RESISTOR_SHIFT 6
|
||||
#define MAX77620_CNFGBBC_RESISTOR_100 (0 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
|
||||
#define MAX77620_CNFGBBC_RESISTOR_1K (1 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
|
||||
#define MAX77620_CNFGBBC_RESISTOR_3K (2 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
|
||||
#define MAX77620_CNFGBBC_RESISTOR_6K (3 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
|
||||
|
||||
#define MAX77620_REG_IRQTOP 0x05
|
||||
#define MAX77620_IRQ_TOP_GLBL_MASK (1 << 7)
|
||||
#define MAX77620_IRQ_TOP_SD_MASK (1 << 6)
|
||||
#define MAX77620_IRQ_TOP_LDO_MASK (1 << 5)
|
||||
#define MAX77620_IRQ_TOP_GPIO_MASK (1 << 4)
|
||||
#define MAX77620_IRQ_TOP_RTC_MASK (1 << 3)
|
||||
#define MAX77620_IRQ_TOP_32K_MASK (1 << 2)
|
||||
#define MAX77620_IRQ_TOP_ONOFF_MASK (1 << 1)
|
||||
|
||||
#define MAX77620_REG_INTLBT 0x06
|
||||
#define MAX77620_REG_IRQTOPM 0x0D
|
||||
#define MAX77620_IRQ_LBM_MASK (1 << 3)
|
||||
#define MAX77620_IRQ_TJALRM1_MASK (1 << 2)
|
||||
#define MAX77620_IRQ_TJALRM2_MASK (1 << 1)
|
||||
|
||||
#define MAX77620_REG_IRQSD 0x07
|
||||
#define MAX77620_REG_IRQ_LVL2_L0_7 0x08
|
||||
#define MAX77620_REG_IRQ_LVL2_L8 0x09
|
||||
#define MAX77620_REG_IRQ_LVL2_GPIO 0x0A
|
||||
#define MAX77620_REG_ONOFFIRQ 0x0B
|
||||
#define MAX77620_REG_NVERC 0x0C
|
||||
|
||||
#define MAX77620_REG_INTENLBT 0x0E
|
||||
#define MAX77620_GLBLM_MASK (1 << 0)
|
||||
|
||||
#define MAX77620_REG_IRQMASKSD 0x0F
|
||||
#define MAX77620_REG_IRQ_MSK_L0_7 0x10
|
||||
#define MAX77620_REG_IRQ_MSK_L8 0x11
|
||||
#define MAX77620_REG_ONOFFIRQM 0x12
|
||||
#define MAX77620_REG_STATLBT 0x13
|
||||
#define MAX77620_REG_STATSD 0x14
|
||||
#define MAX77620_REG_ONOFFSTAT 0x15
|
||||
|
||||
/* SD and LDO Registers */
|
||||
#define MAX77620_REG_SD0 0x16
|
||||
#define MAX77620_REG_SD1 0x17
|
||||
#define MAX77620_REG_SD2 0x18
|
||||
#define MAX77620_REG_SD3 0x19
|
||||
#define MAX77620_REG_SD4 0x1A
|
||||
#define MAX77620_SDX_VOLT_MASK 0xFF
|
||||
#define MAX77620_SD0_VOLT_MASK 0x3F
|
||||
#define MAX77620_SD1_VOLT_MASK 0x7F
|
||||
#define MAX77620_LDO_VOLT_MASK 0x3F
|
||||
#define MAX77620_REG_DVSSD0 0x1B
|
||||
#define MAX77620_REG_DVSSD1 0x1C
|
||||
#define MAX77620_REG_SD0_CFG 0x1D
|
||||
#define MAX77620_REG_SD1_CFG 0x1E
|
||||
#define MAX77620_REG_SD2_CFG 0x1F
|
||||
#define MAX77620_REG_SD3_CFG 0x20
|
||||
#define MAX77620_REG_SD4_CFG 0x21
|
||||
#define MAX77620_REG_SD_CFG2 0x22
|
||||
#define MAX77620_REG_LDO0_CFG 0x23
|
||||
#define MAX77620_REG_LDO0_CFG2 0x24
|
||||
#define MAX77620_REG_LDO1_CFG 0x25
|
||||
#define MAX77620_REG_LDO1_CFG2 0x26
|
||||
#define MAX77620_REG_LDO2_CFG 0x27
|
||||
#define MAX77620_REG_LDO2_CFG2 0x28
|
||||
#define MAX77620_REG_LDO3_CFG 0x29
|
||||
#define MAX77620_REG_LDO3_CFG2 0x2A
|
||||
#define MAX77620_REG_LDO4_CFG 0x2B
|
||||
#define MAX77620_REG_LDO4_CFG2 0x2C
|
||||
#define MAX77620_REG_LDO5_CFG 0x2D
|
||||
#define MAX77620_REG_LDO5_CFG2 0x2E
|
||||
#define MAX77620_REG_LDO6_CFG 0x2F
|
||||
#define MAX77620_REG_LDO6_CFG2 0x30
|
||||
#define MAX77620_REG_LDO7_CFG 0x31
|
||||
#define MAX77620_REG_LDO7_CFG2 0x32
|
||||
#define MAX77620_REG_LDO8_CFG 0x33
|
||||
#define MAX77620_REG_LDO8_CFG2 0x34
|
||||
#define MAX77620_LDO_POWER_MODE_MASK 0xC0
|
||||
#define MAX77620_LDO_POWER_MODE_SHIFT 6
|
||||
#define MAX77620_POWER_MODE_NORMAL 3
|
||||
#define MAX77620_POWER_MODE_LPM 2
|
||||
#define MAX77620_POWER_MODE_GLPM 1
|
||||
#define MAX77620_POWER_MODE_DISABLE 0
|
||||
#define MAX20024_LDO_CFG2_MPOK_MASK (1 << 2)
|
||||
#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
|
||||
#define MAX77620_LDO_CFG2_ADE_DISABLE 0
|
||||
#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
|
||||
#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
|
||||
#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
|
||||
#define MAX77620_LDO_CFG2_SS_SLOW 0
|
||||
|
||||
#define MAX77620_REG_LDO_CFG3 0x35
|
||||
#define MAX77620_TRACK4_MASK (1 << 5)
|
||||
#define MAX77620_TRACK4_SHIFT 5
|
||||
|
||||
#define MAX77620_LDO_SLEW_RATE_MASK 0x1
|
||||
|
||||
#define MAX77620_REG_GPIO0 0x36
|
||||
#define MAX77620_REG_GPIO1 0x37
|
||||
#define MAX77620_REG_GPIO2 0x38
|
||||
#define MAX77620_REG_GPIO3 0x39
|
||||
#define MAX77620_REG_GPIO4 0x3A
|
||||
#define MAX77620_REG_GPIO5 0x3B
|
||||
#define MAX77620_REG_GPIO6 0x3C
|
||||
#define MAX77620_REG_GPIO7 0x3D
|
||||
#define MAX77620_REG_PUE_GPIO 0x3E
|
||||
#define MAX77620_REG_PDE_GPIO 0x3F
|
||||
#define MAX77620_REG_AME_GPIO 0x40
|
||||
|
||||
#define MAX77620_REG_ONOFFCNFG1 0x41
|
||||
#define MAX77620_ONOFFCNFG1_SFT_RST (1 << 7)
|
||||
#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
|
||||
#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
|
||||
#define MAX77620_ONOFFCNFG1_SLPEN (1 << 2)
|
||||
#define MAX77620_ONOFFCNFG1_PWR_OFF (1 << 1)
|
||||
#define MAX20024_ONOFFCNFG1_CLRSE 0x18
|
||||
|
||||
#define MAX77620_REG_ONOFFCNFG2 0x42
|
||||
#define MAX77620_ONOFFCNFG2_SFT_RST_WK (1 << 7)
|
||||
#define MAX77620_ONOFFCNFG2_WD_RST_WK (1 << 6)
|
||||
#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK (1 << 5)
|
||||
#define MAX77620_ONOFFCNFG2_WK_ALARM1 (1 << 2)
|
||||
#define MAX77620_ONOFFCNFG2_WK_EN0 (1 << 0)
|
||||
|
||||
/* FPS Registers */
|
||||
#define MAX77620_REG_FPS_CFG0 0x43
|
||||
#define MAX77620_REG_FPS_CFG1 0x44
|
||||
#define MAX77620_REG_FPS_CFG2 0x45
|
||||
#define MAX77620_REG_FPS_LDO0 0x46
|
||||
#define MAX77620_REG_FPS_LDO1 0x47
|
||||
#define MAX77620_REG_FPS_LDO2 0x48
|
||||
#define MAX77620_REG_FPS_LDO3 0x49
|
||||
#define MAX77620_REG_FPS_LDO4 0x4A
|
||||
#define MAX77620_REG_FPS_LDO5 0x4B
|
||||
#define MAX77620_REG_FPS_LDO6 0x4C
|
||||
#define MAX77620_REG_FPS_LDO7 0x4D
|
||||
#define MAX77620_REG_FPS_LDO8 0x4E
|
||||
#define MAX77620_REG_FPS_SD0 0x4F
|
||||
#define MAX77620_REG_FPS_SD1 0x50
|
||||
#define MAX77620_REG_FPS_SD2 0x51
|
||||
#define MAX77620_REG_FPS_SD3 0x52
|
||||
#define MAX77620_REG_FPS_SD4 0x53
|
||||
#define MAX77620_REG_FPS_NONE 0
|
||||
#define MAX77620_FPS_SRC_MASK 0xC0
|
||||
#define MAX77620_FPS_SRC_SHIFT 6
|
||||
#define MAX77620_FPS_PU_PERIOD_MASK 0x38
|
||||
#define MAX77620_FPS_PU_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_PD_PERIOD_MASK 0x07
|
||||
#define MAX77620_FPS_PD_PERIOD_SHIFT 0
|
||||
|
||||
/* Minimum and maximum FPS period time (in microseconds) are
|
||||
* different for MAX77620 and Max20024.
|
||||
*/
|
||||
#define MAX77620_FPS_COUNT 3
|
||||
|
||||
#define MAX77620_FPS_PERIOD_MIN_US 40
|
||||
#define MAX20024_FPS_PERIOD_MIN_US 20
|
||||
|
||||
#define MAX77620_FPS_PERIOD_MAX_US 2560
|
||||
#define MAX20024_FPS_PERIOD_MAX_US 5120
|
||||
|
||||
#define MAX77620_REG_FPS_GPIO1 0x54
|
||||
#define MAX77620_REG_FPS_GPIO2 0x55
|
||||
#define MAX77620_REG_FPS_GPIO3 0x56
|
||||
#define MAX77620_FPS_TIME_PERIOD_MASK 0x38
|
||||
#define MAX77620_FPS_TIME_PERIOD_SHIFT 3
|
||||
#define MAX77620_FPS_EN_SRC_MASK 0x06
|
||||
#define MAX77620_FPS_EN_SRC_SHIFT 1
|
||||
#define MAX77620_FPS_ENFPS_SW_MASK 0x01
|
||||
#define MAX77620_FPS_ENFPS_SW 0x01
|
||||
|
||||
#define MAX77620_REG_FPS_RSO 0x57
|
||||
#define MAX77620_REG_CID0 0x58
|
||||
#define MAX77620_REG_CID1 0x59
|
||||
#define MAX77620_REG_CID2 0x5A
|
||||
#define MAX77620_REG_CID3 0x5B
|
||||
#define MAX77620_REG_CID4 0x5C
|
||||
#define MAX77620_REG_CID5 0x5D
|
||||
|
||||
#define MAX77620_REG_DVSSD4 0x5E
|
||||
#define MAX20024_REG_MAX_ADD 0x70
|
||||
|
||||
#define MAX77620_CID_DIDM_MASK 0xF0
|
||||
#define MAX77620_CID_DIDM_SHIFT 4
|
||||
|
||||
/* CNCG2SD */
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD1 (1 << 1)
|
||||
#define MAX77620_SD_CNF2_ROVS_EN_SD0 (1 << 2)
|
||||
|
||||
/* Device Identification Metal */
|
||||
#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
|
||||
/* Device Indentification OTP */
|
||||
#define MAX77620_CID5_DIDO(n) ((n) & 0xF)
|
||||
|
||||
/* SD CNFG1 */
|
||||
#define MAX77620_SD_SR_MASK 0xC0
|
||||
#define MAX77620_SD_SR_SHIFT 6
|
||||
#define MAX77620_SD_POWER_MODE_MASK 0x30
|
||||
#define MAX77620_SD_POWER_MODE_SHIFT 4
|
||||
#define MAX77620_SD_CFG1_ADE_MASK (1 << 3)
|
||||
#define MAX77620_SD_CFG1_ADE_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_ADE_ENABLE (1 << 3)
|
||||
#define MAX77620_SD_FPWM_MASK 0x04
|
||||
#define MAX77620_SD_FPWM_SHIFT 2
|
||||
#define MAX77620_SD_FSRADE_MASK 0x01
|
||||
#define MAX77620_SD_FSRADE_SHIFT 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_MASK (1 << 2)
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
|
||||
#define MAX77620_SD_CFG1_FPWM_SD_FPWM (1 << 2)
|
||||
#define MAX20024_SD_CFG1_MPOK_MASK (1 << 1)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_MASK (1 << 0)
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
|
||||
#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE (1 << 0)
|
||||
|
||||
#define MAX77620_CNFG_GPIO_DRV_MASK (1 << 0)
|
||||
#define MAX77620_CNFG_GPIO_DRV_PUSHPULL (1 << 0)
|
||||
#define MAX77620_CNFG_GPIO_DRV_OPENDRAIN 0
|
||||
#define MAX77620_CNFG_GPIO_DIR_MASK (1 << 1)
|
||||
#define MAX77620_CNFG_GPIO_DIR_INPUT (1 << 1)
|
||||
#define MAX77620_CNFG_GPIO_DIR_OUTPUT 0
|
||||
#define MAX77620_CNFG_GPIO_INPUT_VAL_MASK (1 << 2)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK (1 << 3)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH (1 << 3)
|
||||
#define MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW 0
|
||||
#define MAX77620_CNFG_GPIO_INT_MASK (0x3 << 4)
|
||||
#define MAX77620_CNFG_GPIO_INT_FALLING (1 << 4)
|
||||
#define MAX77620_CNFG_GPIO_INT_RISING (1 << 5)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_MASK (0x3 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_None (0x0 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_8ms (0x1 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_16ms (0x2 << 6)
|
||||
#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
|
||||
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE0 (1 << 0)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE1 (1 << 1)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE2 (1 << 2)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE3 (1 << 3)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE4 (1 << 4)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE5 (1 << 5)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE6 (1 << 6)
|
||||
#define MAX77620_IRQ_LVL2_GPIO_EDGE7 (1 << 7)
|
||||
|
||||
/* Interrupts */
|
||||
enum {
|
||||
MAX77620_IRQ_TOP_GLBL, /* Low-Battery */
|
||||
MAX77620_IRQ_TOP_SD, /* SD power fail */
|
||||
MAX77620_IRQ_TOP_LDO, /* LDO power fail */
|
||||
MAX77620_IRQ_TOP_GPIO, /* TOP GPIO internal int to MAX77620 */
|
||||
MAX77620_IRQ_TOP_RTC, /* RTC */
|
||||
MAX77620_IRQ_TOP_32K, /* 32kHz oscillator */
|
||||
MAX77620_IRQ_TOP_ONOFF, /* ON/OFF oscillator */
|
||||
MAX77620_IRQ_LBT_MBATLOW, /* Thermal alarm status, > 120C */
|
||||
MAX77620_IRQ_LBT_TJALRM1, /* Thermal alarm status, > 120C */
|
||||
MAX77620_IRQ_LBT_TJALRM2, /* Thermal alarm status, > 140C */
|
||||
};
|
||||
|
||||
/* GPIOs */
|
||||
enum {
|
||||
MAX77620_GPIO0,
|
||||
MAX77620_GPIO1,
|
||||
MAX77620_GPIO2,
|
||||
MAX77620_GPIO3,
|
||||
MAX77620_GPIO4,
|
||||
MAX77620_GPIO5,
|
||||
MAX77620_GPIO6,
|
||||
MAX77620_GPIO7,
|
||||
MAX77620_GPIO_NR,
|
||||
};
|
||||
|
||||
/* FPS Source */
|
||||
enum max77620_fps_src {
|
||||
MAX77620_FPS_SRC_0,
|
||||
MAX77620_FPS_SRC_1,
|
||||
MAX77620_FPS_SRC_2,
|
||||
MAX77620_FPS_SRC_NONE,
|
||||
MAX77620_FPS_SRC_DEF,
|
||||
};
|
||||
|
||||
enum max77620_chip_id {
|
||||
MAX77620,
|
||||
MAX20024,
|
||||
};
|
||||
|
||||
#endif /* _MFD_MAX77620_H_ */
|
165
emummc/source/power/max7762x.c
Normal file
165
emummc/source/power/max7762x.c
Normal file
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "max7762x.h"
|
||||
#include "max77620.h"
|
||||
#include "../soc/i2c.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
#define REGULATOR_SD 0
|
||||
#define REGULATOR_LDO 1
|
||||
|
||||
typedef struct _max77620_regulator_t
|
||||
{
|
||||
u8 type;
|
||||
const char *name;
|
||||
u8 reg_sd;
|
||||
|
||||
u32 mv_step;
|
||||
u32 mv_min;
|
||||
u32 mv_default;
|
||||
u32 mv_max;
|
||||
|
||||
u8 volt_addr;
|
||||
u8 cfg_addr;
|
||||
|
||||
u8 volt_mask;
|
||||
u8 enable_mask;
|
||||
u8 enable_shift;
|
||||
u8 status_mask;
|
||||
|
||||
u8 fps_addr;
|
||||
u8 fps_src;
|
||||
u8 pd_period;
|
||||
u8 pu_period;
|
||||
} max77620_regulator_t;
|
||||
|
||||
static const max77620_regulator_t _pmic_regulators[] = {
|
||||
{ REGULATOR_SD, "sd0", 0x16, 12500, 600000, 625000, 1400000, MAX77620_REG_SD0, MAX77620_REG_SD0_CFG, MAX77620_SD0_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x80, MAX77620_REG_FPS_SD0, 1, 7, 1 },
|
||||
{ REGULATOR_SD, "sd1", 0x17, 12500, 600000, 1125000, 1125000, MAX77620_REG_SD1, MAX77620_REG_SD1_CFG, MAX77620_SD1_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x40, MAX77620_REG_FPS_SD1, 0, 1, 5 },
|
||||
{ REGULATOR_SD, "sd2", 0x18, 12500, 600000, 1325000, 1350000, MAX77620_REG_SD2, MAX77620_REG_SD2_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x20, MAX77620_REG_FPS_SD2, 1, 5, 2 },
|
||||
{ REGULATOR_SD, "sd3", 0x19, 12500, 600000, 1800000, 1800000, MAX77620_REG_SD3, MAX77620_REG_SD3_CFG, MAX77620_SDX_VOLT_MASK, MAX77620_SD_POWER_MODE_MASK, MAX77620_SD_POWER_MODE_SHIFT, 0x10, MAX77620_REG_FPS_SD3, 0, 3, 3 },
|
||||
{ REGULATOR_LDO, "ldo0", 0x00, 25000, 800000, 1200000, 1200000, MAX77620_REG_LDO0_CFG, MAX77620_REG_LDO0_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO0, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo1", 0x00, 25000, 800000, 1050000, 1050000, MAX77620_REG_LDO1_CFG, MAX77620_REG_LDO1_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO1, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo2", 0x00, 50000, 800000, 1800000, 3300000, MAX77620_REG_LDO2_CFG, MAX77620_REG_LDO2_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO2, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo3", 0x00, 50000, 800000, 3100000, 3100000, MAX77620_REG_LDO3_CFG, MAX77620_REG_LDO3_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO3, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo4", 0x00, 12500, 800000, 850000, 850000, MAX77620_REG_LDO4_CFG, MAX77620_REG_LDO4_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO4, 0, 7, 1 },
|
||||
{ REGULATOR_LDO, "ldo5", 0x00, 50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO5, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo6", 0x00, 50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO6, 3, 7, 0 },
|
||||
{ REGULATOR_LDO, "ldo7", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO7, 1, 4, 3 },
|
||||
{ REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO8, 3, 7, 0 }
|
||||
};
|
||||
|
||||
int max77620_regulator_get_status(u32 id)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
if (reg->type == REGULATOR_SD)
|
||||
return (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_STATSD) & reg->status_mask) ? 0 : 1;
|
||||
return (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->cfg_addr) & 8) ? 1 : 0;
|
||||
}
|
||||
|
||||
int max77620_regulator_config_fps(u32 id)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->fps_addr,
|
||||
(reg->fps_src << MAX77620_FPS_SRC_SHIFT) | (reg->pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) | (reg->pd_period));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int max77620_regulator_set_voltage(u32 id, u32 mv)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
if (mv < reg->mv_min || mv > reg->mv_max)
|
||||
return 0;
|
||||
|
||||
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
||||
u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr);
|
||||
val = (val & ~reg->volt_mask) | (mult & reg->volt_mask);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr, val);
|
||||
usleep(1000);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int max77620_regulator_enable(u32 id, int enable)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
u32 addr = reg->type == REGULATOR_SD ? reg->cfg_addr : reg->volt_addr;
|
||||
u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, addr);
|
||||
if (enable)
|
||||
val = (val & ~reg->enable_mask) | ((MAX77620_POWER_MODE_NORMAL << reg->enable_shift) & reg->enable_mask);
|
||||
else
|
||||
val &= ~reg->enable_mask;
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, addr, val);
|
||||
usleep(1000);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
return 0;
|
||||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
if (mv < reg->mv_min || mv > reg->mv_max)
|
||||
return 0;
|
||||
|
||||
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
||||
u8 val = ((flags << reg->enable_shift) & ~reg->volt_mask) | (mult & reg->volt_mask);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr, val);
|
||||
usleep(1000);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void max77620_config_default()
|
||||
{
|
||||
for (u32 i = 1; i <= REGULATOR_MAX; i++)
|
||||
{
|
||||
i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CID4);
|
||||
max77620_regulator_config_fps(i);
|
||||
max77620_regulator_set_voltage(i, _pmic_regulators[i].mv_default);
|
||||
if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE)
|
||||
max77620_regulator_enable(i, 1);
|
||||
}
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 4);
|
||||
}
|
||||
|
||||
void max77620_low_battery_monitor_config()
|
||||
{
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGGLBL1,
|
||||
MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_LBHYST_N | MAX77620_CNFGGLBL1_LBDAC_N);
|
||||
}
|
116
emummc/source/power/max7762x.h
Normal file
116
emummc/source/power/max7762x.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _MAX7762X_H_
|
||||
#define _MAX7762X_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
/*
|
||||
* Switch Power domains (max77620):
|
||||
* Name | Usage | uV step | uV min | uV default | uV max | Init
|
||||
*-------+---------------+---------+--------+------------+---------+------------------
|
||||
* sd0 | core | 12500 | 600000 | 625000 | 1400000 | 1.125V (pkg1.1)
|
||||
* sd1 | SDRAM | 12500 | 600000 | 1125000 | 1125000 | 1.1V (pkg1.1)
|
||||
* sd2 | ldo{0-1, 7-8} | 12500 | 600000 | 1325000 | 1350000 | 1.325V (pcv)
|
||||
* sd3 | 1.8V general | 12500 | 600000 | 1800000 | 1800000 |
|
||||
* ldo0 | Display Panel | 25000 | 800000 | 1200000 | 1200000 | 1.2V (pkg1.1)
|
||||
* ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
|
||||
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
|
||||
* ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv)
|
||||
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 |
|
||||
* ldo5 | GC ASIC | 50000 | 800000 | 1800000 | 1800000 | 1.8V (pcv)
|
||||
* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V
|
||||
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 |
|
||||
* ldo8 | XUSB, DC | 50000 | 800000 | 1050000 | 1050000 |
|
||||
*/
|
||||
|
||||
/*
|
||||
* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode
|
||||
* MAX77620_REG_GPIOx: 0x9 sets output and enable
|
||||
*/
|
||||
|
||||
/*! MAX77620 partitions. */
|
||||
#define REGULATOR_SD0 0
|
||||
#define REGULATOR_SD1 1
|
||||
#define REGULATOR_SD2 2
|
||||
#define REGULATOR_SD3 3
|
||||
#define REGULATOR_LDO0 4
|
||||
#define REGULATOR_LDO1 5
|
||||
#define REGULATOR_LDO2 6
|
||||
#define REGULATOR_LDO3 7
|
||||
#define REGULATOR_LDO4 8
|
||||
#define REGULATOR_LDO5 9
|
||||
#define REGULATOR_LDO6 10
|
||||
#define REGULATOR_LDO7 11
|
||||
#define REGULATOR_LDO8 12
|
||||
#define REGULATOR_MAX 12
|
||||
|
||||
#define MAX77621_CPU_I2C_ADDR 0x1B
|
||||
#define MAX77621_GPU_I2C_ADDR 0x1C
|
||||
|
||||
#define MAX77621_VOUT_REG 0
|
||||
#define MAX77621_VOUT_DVC_REG 1
|
||||
#define MAX77621_CONTROL1_REG 2
|
||||
#define MAX77621_CONTROL2_REG 3
|
||||
|
||||
/* MAX77621_VOUT */
|
||||
#define MAX77621_VOUT_ENABLE (1 << 7)
|
||||
#define MAX77621_VOUT_MASK 0x7F
|
||||
|
||||
/* MAX77621_VOUT_DVC_DVS */
|
||||
#define MAX77621_DVS_VOUT_MASK 0x7F
|
||||
|
||||
/* MAX77621_CONTROL1 */
|
||||
#define MAX77621_SNS_ENABLE (1 << 7)
|
||||
#define MAX77621_FPWM_EN_M (1 << 6)
|
||||
#define MAX77621_NFSR_ENABLE (1 << 5)
|
||||
#define MAX77621_AD_ENABLE (1 << 4)
|
||||
#define MAX77621_BIAS_ENABLE (1 << 3)
|
||||
#define MAX77621_FREQSHIFT_9PER (1 << 2)
|
||||
|
||||
#define MAX77621_RAMP_12mV_PER_US 0x0
|
||||
#define MAX77621_RAMP_25mV_PER_US 0x1
|
||||
#define MAX77621_RAMP_50mV_PER_US 0x2
|
||||
#define MAX77621_RAMP_200mV_PER_US 0x3
|
||||
#define MAX77621_RAMP_MASK 0x3
|
||||
|
||||
/* MAX77621_CONTROL2 */
|
||||
#define MAX77621_WDTMR_ENABLE (1 << 6)
|
||||
#define MAX77621_DISCH_ENBABLE (1 << 5)
|
||||
#define MAX77621_FT_ENABLE (1 << 4)
|
||||
#define MAX77621_T_JUNCTION_120 (1 << 7)
|
||||
|
||||
#define MAX77621_CKKADV_TRIP_DISABLE 0xC
|
||||
#define MAX77621_CKKADV_TRIP_75mV_PER_US 0x0
|
||||
#define MAX77621_CKKADV_TRIP_150mV_PER_US 0x4
|
||||
#define MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS 0x8
|
||||
|
||||
#define MAX77621_INDUCTOR_MIN_30_PER 0x0
|
||||
#define MAX77621_INDUCTOR_NOMINAL 0x1
|
||||
#define MAX77621_INDUCTOR_PLUS_30_PER 0x2
|
||||
#define MAX77621_INDUCTOR_PLUS_60_PER 0x3
|
||||
|
||||
int max77620_regulator_get_status(u32 id);
|
||||
int max77620_regulator_config_fps(u32 id);
|
||||
int max77620_regulator_set_voltage(u32 id, u32 mv);
|
||||
int max77620_regulator_enable(u32 id, int enable);
|
||||
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags);
|
||||
void max77620_config_default();
|
||||
void max77620_low_battery_monitor_config();
|
||||
|
||||
#endif
|
360
emummc/source/soc/clock.c
Normal file
360
emummc/source/soc/clock.c
Normal file
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../soc/clock.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../emmc/sdmmc.h"
|
||||
|
||||
static const sclock_t _clock_i2c5 = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 0xF, 0, 4 //81.6MHz -> 400KHz
|
||||
};
|
||||
|
||||
void clock_enable(const sclock_t *clk)
|
||||
{
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index);
|
||||
// Disable.
|
||||
CLOCK(clk->enable) &= ~(1 << clk->index);
|
||||
// Configure clock source if required.
|
||||
if (clk->source)
|
||||
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
|
||||
// Enable.
|
||||
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~(1 << clk->index)) | (1 << clk->index);
|
||||
// Take clock off reset.
|
||||
CLOCK(clk->reset) &= ~(1 << clk->index);
|
||||
}
|
||||
|
||||
void clock_disable(const sclock_t *clk)
|
||||
{
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index);
|
||||
// Disable.
|
||||
CLOCK(clk->enable) &= ~(1 << clk->index);
|
||||
}
|
||||
|
||||
void clock_enable_i2c5()
|
||||
{
|
||||
clock_enable(&_clock_i2c5);
|
||||
}
|
||||
|
||||
void clock_disable_i2c5()
|
||||
{
|
||||
clock_disable(&_clock_i2c5);
|
||||
}
|
||||
|
||||
#define L_SWR_SDMMC1_RST (1 << 14)
|
||||
#define L_SWR_SDMMC2_RST (1 << 9)
|
||||
#define L_SWR_SDMMC4_RST (1 << 15)
|
||||
#define U_SWR_SDMMC3_RST (1 << 5)
|
||||
|
||||
#define L_CLK_ENB_SDMMC1 (1 << 14)
|
||||
#define L_CLK_ENB_SDMMC2 (1 << 9)
|
||||
#define L_CLK_ENB_SDMMC4 (1 << 15)
|
||||
#define U_CLK_ENB_SDMMC3 (1 << 5)
|
||||
|
||||
#define L_SET_SDMMC1_RST (1 << 14)
|
||||
#define L_SET_SDMMC2_RST (1 << 9)
|
||||
#define L_SET_SDMMC4_RST (1 << 15)
|
||||
#define U_SET_SDMMC3_RST (1 << 5)
|
||||
|
||||
#define L_CLR_SDMMC1_RST (1 << 14)
|
||||
#define L_CLR_SDMMC2_RST (1 << 9)
|
||||
#define L_CLR_SDMMC4_RST (1 << 15)
|
||||
#define U_CLR_SDMMC3_RST (1 << 5)
|
||||
|
||||
#define L_SET_CLK_ENB_SDMMC1 (1 << 14)
|
||||
#define L_SET_CLK_ENB_SDMMC2 (1 << 9)
|
||||
#define L_SET_CLK_ENB_SDMMC4 (1 << 15)
|
||||
#define U_SET_CLK_ENB_SDMMC3 (1 << 5)
|
||||
|
||||
#define L_CLR_CLK_ENB_SDMMC1 (1 << 14)
|
||||
#define L_CLR_CLK_ENB_SDMMC2 (1 << 9)
|
||||
#define L_CLR_CLK_ENB_SDMMC4 (1 << 15)
|
||||
#define U_CLR_CLK_ENB_SDMMC3 (1 << 5)
|
||||
|
||||
static int _clock_sdmmc_is_reset(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC1_RST;
|
||||
case SDMMC_2:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC2_RST;
|
||||
case SDMMC_3:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & U_SWR_SDMMC3_RST;
|
||||
case SDMMC_4:
|
||||
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC4_RST;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_set_reset(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC1_RST;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC2_RST;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = U_SET_SDMMC3_RST;
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC4_RST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_clear_reset(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC1_RST;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC2_RST;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = U_CLR_SDMMC3_RST;
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC4_RST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _clock_sdmmc_is_enabled(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC1;
|
||||
case SDMMC_2:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC2;
|
||||
case SDMMC_3:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & U_CLK_ENB_SDMMC3;
|
||||
case SDMMC_4:
|
||||
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_set_enable(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC1;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC2;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = U_SET_CLK_ENB_SDMMC3;
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void _clock_sdmmc_clear_enable(u32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC1;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC2;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = U_CLR_CLK_ENB_SDMMC3;
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 _clock_sdmmc_table[8] = { 0 };
|
||||
|
||||
#define PLLP_OUT0 0x0
|
||||
|
||||
static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)
|
||||
{
|
||||
u32 divisor = 0;
|
||||
u32 source = PLLP_OUT0;
|
||||
|
||||
switch (val)
|
||||
{
|
||||
case 25000:
|
||||
*pout = 24728;
|
||||
divisor = 31;
|
||||
break;
|
||||
case 26000:
|
||||
*pout = 25500;
|
||||
divisor = 30;
|
||||
break;
|
||||
case 40800:
|
||||
*pout = 40800;
|
||||
divisor = 18;
|
||||
break;
|
||||
case 50000:
|
||||
*pout = 48000;
|
||||
divisor = 15;
|
||||
break;
|
||||
case 52000:
|
||||
*pout = 51000;
|
||||
divisor = 14;
|
||||
break;
|
||||
case 100000:
|
||||
*pout = 90667;
|
||||
divisor = 7;
|
||||
break;
|
||||
case 200000:
|
||||
*pout = 163200;
|
||||
divisor = 3;
|
||||
break;
|
||||
case 208000:
|
||||
*pout = 204000;
|
||||
divisor = 2;
|
||||
break;
|
||||
default:
|
||||
*pout = 24728;
|
||||
divisor = 31;
|
||||
}
|
||||
|
||||
_clock_sdmmc_table[2 * id] = val;
|
||||
_clock_sdmmc_table[2 * id + 1] = *pout;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = (source << 29) | divisor;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = (source << 29) | divisor;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = (source << 29) | divisor;
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = (source << 29) | divisor;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val)
|
||||
{
|
||||
if (_clock_sdmmc_table[2 * id] == val)
|
||||
{
|
||||
*pout = _clock_sdmmc_table[2 * id + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
int is_enabled = _clock_sdmmc_is_enabled(id);
|
||||
if (is_enabled)
|
||||
_clock_sdmmc_clear_enable(id);
|
||||
_clock_sdmmc_config_clock_source_inner(pout, id, val);
|
||||
if (is_enabled)
|
||||
_clock_sdmmc_set_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
}
|
||||
}
|
||||
|
||||
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
*pout = 26000;
|
||||
*pdivisor = 66;
|
||||
break;
|
||||
case 1:
|
||||
*pout = 26000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case 2:
|
||||
*pout = 52000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 11:
|
||||
*pout = 200000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case 5:
|
||||
*pout = 25000;
|
||||
*pdivisor = 64;
|
||||
break;
|
||||
case 6:
|
||||
case 8:
|
||||
*pout = 25000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case 7:
|
||||
*pout = 50000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case 10:
|
||||
*pout = 100000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case 13:
|
||||
*pout = 40800;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case 14:
|
||||
*pout = 200000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id)
|
||||
{
|
||||
return !_clock_sdmmc_is_reset(id) && _clock_sdmmc_is_enabled(id);
|
||||
}
|
||||
|
||||
void clock_sdmmc_enable(u32 id, u32 val)
|
||||
{
|
||||
u32 div = 0;
|
||||
|
||||
if (_clock_sdmmc_is_enabled(id))
|
||||
_clock_sdmmc_clear_enable(id);
|
||||
_clock_sdmmc_set_reset(id);
|
||||
_clock_sdmmc_config_clock_source_inner(&div, id, val);
|
||||
_clock_sdmmc_set_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
usleep((100000 + div - 1) / div);
|
||||
_clock_sdmmc_clear_reset(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
}
|
||||
|
||||
void clock_sdmmc_disable(u32 id)
|
||||
{
|
||||
_clock_sdmmc_set_reset(id);
|
||||
_clock_sdmmc_clear_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
}
|
145
emummc/source/soc/clock.h
Normal file
145
emummc/source/soc/clock.h
Normal file
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CLOCK_H_
|
||||
#define _CLOCK_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
/*! Clock registers. */
|
||||
#define CLK_RST_CONTROLLER_RST_SOURCE 0x0
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_L 0x4
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_H 0x8
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_U 0xC
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_L 0x10
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_H 0x14
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_U 0x18
|
||||
#define CLK_RST_CONTROLLER_CCLK_BURST_POLICY 0x20
|
||||
#define CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER 0x24
|
||||
#define CLK_RST_CONTROLLER_SCLK_BURST_POLICY 0x28
|
||||
#define CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER 0x2C
|
||||
#define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30
|
||||
#define CLK_RST_CONTROLLER_MISC_CLK_ENB 0x48
|
||||
#define CLK_RST_CONTROLLER_OSC_CTRL 0x50
|
||||
#define CLK_RST_CONTROLLER_PLLC_BASE 0x80
|
||||
#define CLK_RST_CONTROLLER_PLLC_MISC 0x88
|
||||
#define CLK_RST_CONTROLLER_PLLM_BASE 0x90
|
||||
#define CLK_RST_CONTROLLER_PLLM_MISC1 0x98
|
||||
#define CLK_RST_CONTROLLER_PLLM_MISC2 0x9C
|
||||
#define CLK_RST_CONTROLLER_PLLP_BASE 0xA0
|
||||
#define CLK_RST_CONTROLLER_PLLD_BASE 0xD0
|
||||
#define CLK_RST_CONTROLLER_PLLX_BASE 0xE0
|
||||
#define CLK_RST_CONTROLLER_PLLX_MISC 0xE4
|
||||
#define CLK_RST_CONTROLLER_PLLE_BASE 0xE8
|
||||
#define CLK_RST_CONTROLLER_PLLE_MISC 0xEC
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA 0xF8
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB 0xFC
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_PWM 0x110
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C1 0x124
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C5 0x128
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_VI 0x148
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1 0x150
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2 0x154
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4 0x164
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA 0x178
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB 0x17C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X 0x180
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC 0x1A0
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C3 0x1B8
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3 0x1BC
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_CSITE 0x1D4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_TSEC 0x1F4
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X 0x280
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_X_CLR 0x288
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_X 0x28C
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_X_SET 0x290
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_X_CLR 0x294
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_Y 0x298
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_Y_SET 0x29C
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_Y_CLR 0x2A0
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_Y 0x2A4
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2A8
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2AC
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_L_SET 0x300
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_L_CLR 0x304
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_H_CLR 0x30C
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_U_SET 0x310
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_U_CLR 0x314
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_L_SET 0x320
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_L_CLR 0x324
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_H_CLR 0x32C
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_U_SET 0x330
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_U_CLR 0x334
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_V 0x358
|
||||
#define CLK_RST_CONTROLLER_RST_DEVICES_W 0x35C
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_V 0x360
|
||||
#define CLK_RST_CONTROLLER_CLK_OUT_ENB_W 0x364
|
||||
#define CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2 0x388
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC 0x3A0
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3A4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_V_SET 0x440
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_W_SET 0x448
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_W_CLR 0x44C
|
||||
#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET 0x450
|
||||
#define CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR 0x454
|
||||
#define CLK_RST_CONTROLLER_UTMIP_PLL_CFG2 0x488
|
||||
#define CLK_RST_CONTROLLER_PLLE_AUX 0x48C
|
||||
#define CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S0 0x4A0
|
||||
#define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518
|
||||
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE 0x554
|
||||
#define CLK_RST_CONTROLLER_SPARE_REG0 0x55C
|
||||
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP 0x620
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIP_CAL 0x66C
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0
|
||||
#define CLK_RST_CONTROLLER_SE_SUPER_CLK_DIVIDER 0x704
|
||||
|
||||
#define CLK_NO_SOURCE 0x0
|
||||
|
||||
/*! Generic clock descriptor. */
|
||||
typedef struct _sclock_t
|
||||
{
|
||||
u32 reset;
|
||||
u32 enable;
|
||||
u32 source;
|
||||
u8 index;
|
||||
u8 clk_src;
|
||||
u8 clk_div;
|
||||
} sclock_t;
|
||||
|
||||
/*! Generic clock enable/disable. */
|
||||
void clock_enable(const sclock_t *clk);
|
||||
void clock_disable(const sclock_t *clk);
|
||||
|
||||
/*! Clock control for specific hardware portions. */
|
||||
void clock_enable_i2c5();
|
||||
void clock_disable_i2c5();
|
||||
void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val);
|
||||
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type);
|
||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
||||
void clock_sdmmc_enable(u32 id, u32 val);
|
||||
void clock_sdmmc_disable(u32 id);
|
||||
|
||||
#endif
|
94
emummc/source/soc/gpio.c
Normal file
94
emummc/source/soc/gpio.c
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../soc/gpio.h"
|
||||
#include "../soc/t210.h"
|
||||
|
||||
static const u16 _gpio_cnf[31] = {
|
||||
0x000, 0x004, 0x008, 0x00C,
|
||||
0x100, 0x104, 0x108, 0x10C,
|
||||
0x200, 0x204, 0x208, 0x20C,
|
||||
0x300, 0x304, 0x308, 0x30C,
|
||||
0x400, 0x404, 0x408, 0x40C,
|
||||
0x500, 0x504, 0x508, 0x50C,
|
||||
0x600, 0x604, 0x608, 0x60C,
|
||||
0x700, 0x704, 0x708
|
||||
};
|
||||
|
||||
static const u16 _gpio_oe[31] = {
|
||||
0x010, 0x014, 0x018, 0x01C,
|
||||
0x110, 0x114, 0x118, 0x11C,
|
||||
0x210, 0x214, 0x218, 0x21C,
|
||||
0x310, 0x314, 0x318, 0x31C,
|
||||
0x410, 0x414, 0x418, 0x41C,
|
||||
0x510, 0x514, 0x518, 0x51C,
|
||||
0x610, 0x614, 0x618, 0x61C,
|
||||
0x710, 0x714, 0x718
|
||||
};
|
||||
|
||||
static const u16 _gpio_out[31] = {
|
||||
0x020, 0x024, 0x028, 0x02C,
|
||||
0x120, 0x124, 0x128, 0x12C,
|
||||
0x220, 0x224, 0x228, 0x22C,
|
||||
0x320, 0x324, 0x328, 0x32C,
|
||||
0x420, 0x424, 0x428, 0x42C,
|
||||
0x520, 0x524, 0x528, 0x52C,
|
||||
0x620, 0x624, 0x628, 0x62C,
|
||||
0x720, 0x724, 0x728
|
||||
};
|
||||
|
||||
static const u16 _gpio_in[31] = {
|
||||
0x030, 0x034, 0x038, 0x03C,
|
||||
0x130, 0x134, 0x138, 0x13C,
|
||||
0x230, 0x234, 0x238, 0x23C,
|
||||
0x330, 0x334, 0x338, 0x33C,
|
||||
0x430, 0x434, 0x438, 0x43C,
|
||||
0x530, 0x534, 0x538, 0x53C,
|
||||
0x630, 0x634, 0x638, 0x63C,
|
||||
0x730, 0x734, 0x738
|
||||
};
|
||||
|
||||
void gpio_config(u32 port, u32 pins, int mode)
|
||||
{
|
||||
if (mode)
|
||||
GPIO(_gpio_cnf[port]) |= pins;
|
||||
else
|
||||
GPIO(_gpio_cnf[port]) &= ~pins;
|
||||
(void)GPIO(_gpio_cnf[port]);
|
||||
}
|
||||
|
||||
void gpio_output_enable(u32 port, u32 pins, int enable)
|
||||
{
|
||||
if (enable)
|
||||
GPIO(_gpio_oe[port]) |= pins;
|
||||
else
|
||||
GPIO(_gpio_oe[port]) &= ~pins;
|
||||
(void)GPIO(_gpio_oe[port]);
|
||||
}
|
||||
|
||||
void gpio_write(u32 port, u32 pins, int high)
|
||||
{
|
||||
if (high)
|
||||
GPIO(_gpio_out[port]) |= pins;
|
||||
else
|
||||
GPIO(_gpio_out[port]) &= ~pins;
|
||||
(void)GPIO(_gpio_out[port]);
|
||||
}
|
||||
|
||||
int gpio_read(u32 port, u32 pins)
|
||||
{
|
||||
return (GPIO(_gpio_in[port]) & pins) ? 1 : 0;
|
||||
}
|
77
emummc/source/soc/gpio.h
Normal file
77
emummc/source/soc/gpio.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _GPIO_H_
|
||||
#define _GPIO_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
#define GPIO_MODE_SPIO 0
|
||||
#define GPIO_MODE_GPIO 1
|
||||
#define GPIO_OUTPUT_DISABLE 0
|
||||
#define GPIO_OUTPUT_ENABLE 1
|
||||
#define GPIO_LOW 0
|
||||
#define GPIO_HIGH 1
|
||||
|
||||
/*! GPIO pins (0-7 for each port). */
|
||||
#define GPIO_PIN_0 (1 << 0)
|
||||
#define GPIO_PIN_1 (1 << 1)
|
||||
#define GPIO_PIN_2 (1 << 2)
|
||||
#define GPIO_PIN_3 (1 << 3)
|
||||
#define GPIO_PIN_4 (1 << 4)
|
||||
#define GPIO_PIN_5 (1 << 5)
|
||||
#define GPIO_PIN_6 (1 << 6)
|
||||
#define GPIO_PIN_7 (1 << 7)
|
||||
|
||||
/*! GPIO ports (A-EE). */
|
||||
#define GPIO_PORT_A 0
|
||||
#define GPIO_PORT_B 1
|
||||
#define GPIO_PORT_C 2
|
||||
#define GPIO_PORT_D 3
|
||||
#define GPIO_PORT_E 4
|
||||
#define GPIO_PORT_F 5
|
||||
#define GPIO_PORT_G 6
|
||||
#define GPIO_PORT_H 7
|
||||
#define GPIO_PORT_I 8
|
||||
#define GPIO_PORT_J 9
|
||||
#define GPIO_PORT_K 10
|
||||
#define GPIO_PORT_L 11
|
||||
#define GPIO_PORT_M 12
|
||||
#define GPIO_PORT_N 13
|
||||
#define GPIO_PORT_O 14
|
||||
#define GPIO_PORT_P 15
|
||||
#define GPIO_PORT_Q 16
|
||||
#define GPIO_PORT_R 17
|
||||
#define GPIO_PORT_S 18
|
||||
#define GPIO_PORT_T 19
|
||||
#define GPIO_PORT_U 20
|
||||
#define GPIO_PORT_V 21
|
||||
#define GPIO_PORT_W 22
|
||||
#define GPIO_PORT_X 23
|
||||
#define GPIO_PORT_Y 24
|
||||
#define GPIO_PORT_Z 25
|
||||
#define GPIO_PORT_AA 26
|
||||
#define GPIO_PORT_BB 27
|
||||
#define GPIO_PORT_CC 28
|
||||
#define GPIO_PORT_DD 29
|
||||
#define GPIO_PORT_EE 30
|
||||
|
||||
void gpio_config(u32 port, u32 pins, int mode);
|
||||
void gpio_output_enable(u32 port, u32 pins, int enable);
|
||||
void gpio_write(u32 port, u32 pins, int high);
|
||||
int gpio_read(u32 port, u32 pins);
|
||||
|
||||
#endif
|
148
emummc/source/soc/i2c.c
Normal file
148
emummc/source/soc/i2c.c
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "i2c.h"
|
||||
#include "../utils/util.h"
|
||||
#include "t210.h"
|
||||
|
||||
static u32 i2c_addrs[] = {
|
||||
0x7000C000, 0x7000C400, 0x7000C500,
|
||||
0x7000C700, 0x7000D000, 0x7000D100
|
||||
};
|
||||
|
||||
static void _i2c_wait(vu32 *base)
|
||||
{
|
||||
base[I2C_CONFIG_LOAD] = 0x25;
|
||||
for (u32 i = 0; i < 20; i++)
|
||||
{
|
||||
usleep(1);
|
||||
if (!(base[I2C_CONFIG_LOAD] & 1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
|
||||
{
|
||||
if (size > 4)
|
||||
return 0;
|
||||
|
||||
u32 tmp = 0;
|
||||
memcpy(&tmp, buf, size);
|
||||
|
||||
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[0], 0x2000);
|
||||
base = base + (i2c_addrs[idx] - i2c_addrs[0]);
|
||||
base[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).
|
||||
base[I2C_CMD_DATA1] = tmp; //Set value.
|
||||
base[I2C_CNFG] = (2 * size - 2) | 0x2800; //Set size and send mode.
|
||||
_i2c_wait(base); //Kick transaction.
|
||||
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
|
||||
while (base[I2C_STATUS] & 0x100)
|
||||
;
|
||||
|
||||
if (base[I2C_STATUS] << 28)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
|
||||
{
|
||||
if (size > 8)
|
||||
return 0;
|
||||
|
||||
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[0], 0x2000);
|
||||
base = base + (i2c_addrs[idx] - i2c_addrs[0]);
|
||||
|
||||
base[I2C_CMD_ADDR0] = (x << 1) | 1; // Set x (recv mode).
|
||||
base[I2C_CNFG] = (size - 1) << 1 | 0x2840; // Set size and recv mode.
|
||||
_i2c_wait(base); // Kick transaction.
|
||||
|
||||
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
|
||||
while (base[I2C_STATUS] & 0x100)
|
||||
;
|
||||
|
||||
if (base[I2C_STATUS] << 28)
|
||||
return 0;
|
||||
|
||||
u32 tmp = base[I2C_CMD_DATA1]; // Get LS value.
|
||||
if (size > 4)
|
||||
{
|
||||
memcpy(buf, &tmp, 4);
|
||||
tmp = base[I2C_CMD_DATA2]; // Get MS value.
|
||||
memcpy(buf + 4, &tmp, size - 4);
|
||||
}
|
||||
else
|
||||
memcpy(buf, &tmp, size);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void i2c_init(u32 idx)
|
||||
{
|
||||
vu32 *base = (vu32 *)QueryIoMapping(i2c_addrs[0], 0x2000);
|
||||
base = base + (i2c_addrs[idx] - i2c_addrs[0]);
|
||||
|
||||
base[I2C_CLK_DIVISOR_REGISTER] = 0x50001;
|
||||
base[I2C_BUS_CLEAR_CONFIG] = 0x90003;
|
||||
_i2c_wait(base);
|
||||
|
||||
for (u32 i = 0; i < 10; i++)
|
||||
{
|
||||
usleep(20000);
|
||||
if (base[INTERRUPT_STATUS_REGISTER] & 0x800)
|
||||
break;
|
||||
}
|
||||
|
||||
(vu32)base[I2C_BUS_CLEAR_STATUS];
|
||||
base[INTERRUPT_STATUS_REGISTER] = base[INTERRUPT_STATUS_REGISTER];
|
||||
}
|
||||
|
||||
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
|
||||
{
|
||||
u8 tmp[4];
|
||||
|
||||
if (size > 3)
|
||||
return 0;
|
||||
|
||||
tmp[0] = y;
|
||||
memcpy(tmp + 1, buf, size);
|
||||
|
||||
return _i2c_send_pkt(idx, x, tmp, size + 1);
|
||||
}
|
||||
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
|
||||
{
|
||||
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);
|
||||
if (res)
|
||||
res = _i2c_recv_pkt(idx, buf, size, x);
|
||||
return res;
|
||||
}
|
||||
|
||||
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b)
|
||||
{
|
||||
return i2c_send_buf_small(idx, x, y, &b, 1);
|
||||
}
|
||||
|
||||
u8 i2c_recv_byte(u32 idx, u32 x, u32 y)
|
||||
{
|
||||
u8 tmp = 0;
|
||||
i2c_recv_buf_small(&tmp, 1, idx, x, y);
|
||||
return tmp;
|
||||
}
|
||||
|
46
emummc/source/soc/i2c.h
Normal file
46
emummc/source/soc/i2c.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _I2C_H_
|
||||
#define _I2C_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
#define I2C_1 0
|
||||
#define I2C_2 1
|
||||
#define I2C_3 2
|
||||
#define I2C_4 3
|
||||
#define I2C_5 4
|
||||
#define I2C_6 5
|
||||
|
||||
#define I2C_CNFG 0x00
|
||||
#define I2C_CMD_ADDR0 0x01
|
||||
#define I2C_CMD_DATA1 0x03
|
||||
#define I2C_CMD_DATA2 0x04
|
||||
#define I2C_STATUS 0x07
|
||||
#define INTERRUPT_STATUS_REGISTER 0x1A
|
||||
#define I2C_CLK_DIVISOR_REGISTER 0x1B
|
||||
#define I2C_BUS_CLEAR_CONFIG 0x21
|
||||
#define I2C_BUS_CLEAR_STATUS 0x22
|
||||
#define I2C_CONFIG_LOAD 0x23
|
||||
|
||||
void i2c_init(u32 idx);
|
||||
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);
|
||||
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
|
||||
u8 i2c_recv_byte(u32 idx, u32 x, u32 y);
|
||||
|
||||
#endif
|
24
emummc/source/soc/pinmux.c
Normal file
24
emummc/source/soc/pinmux.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../soc/pinmux.h"
|
||||
#include "../soc/t210.h"
|
||||
|
||||
void pinmux_config_i2c(u32 idx)
|
||||
{
|
||||
PINMUX_AUX(PINMUX_AUX_X_I2C_SCL(idx)) = PINMUX_INPUT_ENABLE;
|
||||
PINMUX_AUX(PINMUX_AUX_X_I2C_SDA(idx)) = PINMUX_INPUT_ENABLE;
|
||||
}
|
88
emummc/source/soc/pinmux.h
Normal file
88
emummc/source/soc/pinmux.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _PINMUX_H_
|
||||
#define _PINMUX_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
/*! APB MISC registers. */
|
||||
#define APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL 0x8D4
|
||||
#define APB_MISC_GP_SDMMC3_CLK_LPBK_CONTROL 0x8D8
|
||||
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
|
||||
#define APB_MISC_GP_VGPIO_GPIO_MUX_SEL 0xB74
|
||||
|
||||
/*! Pinmux registers. */
|
||||
#define PINMUX_AUX_SDMMC1_CLK 0x00
|
||||
#define PINMUX_AUX_SDMMC1_CMD 0x04
|
||||
#define PINMUX_AUX_SDMMC1_DAT3 0x08
|
||||
#define PINMUX_AUX_SDMMC1_DAT2 0x0C
|
||||
#define PINMUX_AUX_SDMMC1_DAT1 0x10
|
||||
#define PINMUX_AUX_SDMMC1_DAT0 0x14
|
||||
#define PINMUX_AUX_SDMMC3_CLK 0x1C
|
||||
#define PINMUX_AUX_SDMMC3_CMD 0x20
|
||||
#define PINMUX_AUX_SDMMC3_DAT0 0x24
|
||||
#define PINMUX_AUX_SDMMC3_DAT1 0x28
|
||||
#define PINMUX_AUX_SDMMC3_DAT2 0x2C
|
||||
#define PINMUX_AUX_SDMMC3_DAT3 0x30
|
||||
#define PINMUX_AUX_DMIC3_CLK 0xB4
|
||||
#define PINMUX_AUX_UART2_TX 0xF4
|
||||
#define PINMUX_AUX_UART3_TX 0x104
|
||||
#define PINMUX_AUX_WIFI_EN 0x1B4
|
||||
#define PINMUX_AUX_WIFI_RST 0x1B8
|
||||
#define PINMUX_AUX_NFC_EN 0x1D0
|
||||
#define PINMUX_AUX_NFC_INT 0x1D4
|
||||
#define PINMUX_AUX_LCD_BL_PWM 0x1FC
|
||||
#define PINMUX_AUX_LCD_BL_EN 0x200
|
||||
#define PINMUX_AUX_LCD_RST 0x204
|
||||
#define PINMUX_AUX_GPIO_PE6 0x248
|
||||
#define PINMUX_AUX_GPIO_PH6 0x250
|
||||
#define PINMUX_AUX_GPIO_PZ1 0x280
|
||||
/*! 0:UART-A, 1:UART-B, 3:UART-C, 3:UART-D */
|
||||
#define PINMUX_AUX_UARTX_TX(x) (0xE4 + 0x10 * (x))
|
||||
#define PINMUX_AUX_UARTX_RX(x) (0xE8 + 0x10 * (x))
|
||||
#define PINMUX_AUX_UARTX_RTS(x) (0xEC + 0x10 * (x))
|
||||
#define PINMUX_AUX_UARTX_CTS(x) (0xF0 + 0x10 * (x))
|
||||
/*! 0:GEN1, 1:GEN2, 2:GEN3, 3:CAM, 4:PWR */
|
||||
#define PINMUX_AUX_X_I2C_SCL(x) (0xBC + 8 * (x))
|
||||
#define PINMUX_AUX_X_I2C_SDA(x) (0xC0 + 8 * (x))
|
||||
|
||||
#define PINMUX_FUNC_MASK (3 << 0)
|
||||
|
||||
#define PINMUX_PULL_MASK (3 << 2)
|
||||
#define PINMUX_PULL_NONE (0 << 2)
|
||||
#define PINMUX_PULL_DOWN (1 << 2)
|
||||
#define PINMUX_PULL_UP (2 << 2)
|
||||
|
||||
#define PINMUX_TRISTATE (1 << 4)
|
||||
#define PINMUX_PARKED (1 << 5)
|
||||
#define PINMUX_INPUT_ENABLE (1 << 6)
|
||||
#define PINMUX_LOCK (1 << 7)
|
||||
#define PINMUX_LPDR (1 << 8)
|
||||
#define PINMUX_HSM (1 << 9)
|
||||
|
||||
#define PINMUX_IO_HV (1 << 10)
|
||||
#define PINMUX_OPEN_DRAIN (1 << 11)
|
||||
#define PINMUX_SCHMT (1 << 12)
|
||||
|
||||
#define PINMUX_DRIVE_1X (0 << 13)
|
||||
#define PINMUX_DRIVE_2X (1 << 13)
|
||||
#define PINMUX_DRIVE_3X (2 << 13)
|
||||
#define PINMUX_DRIVE_4X (3 << 13)
|
||||
|
||||
void pinmux_config_i2c(u32 idx);
|
||||
|
||||
#endif
|
71
emummc/source/soc/pmc.h
Normal file
71
emummc/source/soc/pmc.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _PMC_H_
|
||||
#define _PMC_H_
|
||||
|
||||
/*! PMC registers. */
|
||||
#define APBDEV_PMC_CNTRL 0x0
|
||||
#define PMC_CNTRL_MAIN_RST (1 << 4)
|
||||
#define APBDEV_PMC_SEC_DISABLE 0x4
|
||||
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
|
||||
#define APBDEV_PMC_PWRGATE_STATUS 0x38
|
||||
#define APBDEV_PMC_NO_IOPOWER 0x44
|
||||
#define APBDEV_PMC_SCRATCH0 0x50
|
||||
#define APBDEV_PMC_SCRATCH1 0x54
|
||||
#define APBDEV_PMC_SCRATCH20 0xA0
|
||||
#define APBDEV_PMC_PWR_DET_VAL 0xE4
|
||||
#define PMC_PWR_DET_SDMMC1_IO_EN (1 << 12)
|
||||
#define APBDEV_PMC_DDR_PWR 0xE8
|
||||
#define APBDEV_PMC_CRYPTO_OP 0xF4
|
||||
#define PMC_CRYPTO_OP_SE_ENABLE 0
|
||||
#define PMC_CRYPTO_OP_SE_DISABLE 1
|
||||
#define APBDEV_PMC_SCRATCH33 0x120
|
||||
#define APBDEV_PMC_SCRATCH40 0x13C
|
||||
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
|
||||
#define APBDEV_PMC_RST_STATUS 0x1B4
|
||||
#define APBDEV_PMC_IO_DPD_REQ 0x1B8
|
||||
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0
|
||||
#define APBDEV_PMC_VDDP_SEL 0x1CC
|
||||
#define APBDEV_PMC_DDR_CFG 0x1D0
|
||||
#define APBDEV_PMC_SCRATCH45 0x234
|
||||
#define APBDEV_PMC_SCRATCH46 0x238
|
||||
#define APBDEV_PMC_SCRATCH49 0x244
|
||||
#define APBDEV_PMC_TSC_MULT 0x2B4
|
||||
#define APBDEV_PMC_SEC_DISABLE2 0x2C4
|
||||
#define APBDEV_PMC_WEAK_BIAS 0x2C8
|
||||
#define APBDEV_PMC_REG_SHORT 0x2CC
|
||||
#define APBDEV_PMC_SEC_DISABLE3 0x2D8
|
||||
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
|
||||
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
|
||||
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
|
||||
#define APBDEV_PMC_CNTRL2 0x440
|
||||
#define APBDEV_PMC_IO_DPD3_REQ 0x45C
|
||||
#define APBDEV_PMC_IO_DPD4_REQ 0x464
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
|
||||
#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC
|
||||
#define APBDEV_PMC_DDR_CNTRL 0x4E4
|
||||
#define APBDEV_PMC_SEC_DISABLE4 0x5B0
|
||||
#define APBDEV_PMC_SEC_DISABLE5 0x5B4
|
||||
#define APBDEV_PMC_SEC_DISABLE6 0x5B8
|
||||
#define APBDEV_PMC_SEC_DISABLE7 0x5BC
|
||||
#define APBDEV_PMC_SEC_DISABLE8 0x5C0
|
||||
#define APBDEV_PMC_SCRATCH188 0x810
|
||||
#define APBDEV_PMC_SCRATCH190 0x818
|
||||
#define APBDEV_PMC_SCRATCH200 0x840
|
||||
|
||||
#endif
|
564
emummc/source/soc/pmc_lp0_t210.h
Normal file
564
emummc/source/soc/pmc_lp0_t210.h
Normal file
|
@ -0,0 +1,564 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA210_PMC_H_
|
||||
#define _TEGRA210_PMC_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
struct tegra_pmc_regs
|
||||
{
|
||||
u32 cntrl;
|
||||
u32 sec_disable;
|
||||
u32 pmc_swrst;
|
||||
u32 wake_mask;
|
||||
u32 wake_lvl;
|
||||
u32 wake_status;
|
||||
u32 sw_wake_status;
|
||||
u32 dpd_pads_oride;
|
||||
u32 dpd_sample;
|
||||
u32 dpd_enable;
|
||||
u32 pwrgate_timer_off;
|
||||
u32 clamp_status;
|
||||
u32 pwrgate_toggle;
|
||||
u32 remove_clamping_cmd;
|
||||
u32 pwrgate_status;
|
||||
u32 pwrgood_timer;
|
||||
u32 blink_timer;
|
||||
u32 no_iopower;
|
||||
u32 pwr_det;
|
||||
u32 pwr_det_latch;
|
||||
u32 scratch0;
|
||||
u32 scratch1;
|
||||
u32 scratch2;
|
||||
u32 scratch3;
|
||||
u32 scratch4;
|
||||
u32 scratch5;
|
||||
u32 scratch6;
|
||||
u32 scratch7;
|
||||
u32 scratch8;
|
||||
u32 scratch9;
|
||||
u32 scratch10;
|
||||
u32 scratch11;
|
||||
u32 scratch12;
|
||||
u32 scratch13;
|
||||
u32 scratch14;
|
||||
u32 scratch15;
|
||||
u32 scratch16;
|
||||
u32 scratch17;
|
||||
u32 scratch18;
|
||||
u32 scratch19;
|
||||
u32 odmdata;
|
||||
u32 scratch21;
|
||||
u32 scratch22;
|
||||
u32 scratch23;
|
||||
u32 secure_scratch0;
|
||||
u32 secure_scratch1;
|
||||
u32 secure_scratch2;
|
||||
u32 secure_scratch3;
|
||||
u32 secure_scratch4;
|
||||
u32 secure_scratch5;
|
||||
u32 cpupwrgood_timer;
|
||||
u32 cpupwroff_timer;
|
||||
u32 pg_mask;
|
||||
u32 pg_mask_1;
|
||||
u32 auto_wake_lvl;
|
||||
u32 auto_wake_lvl_mask;
|
||||
u32 wake_delay;
|
||||
u32 pwr_det_val;
|
||||
u32 ddr_pwr;
|
||||
u32 usb_debounce_del;
|
||||
u32 usb_a0;
|
||||
u32 crypto_op;
|
||||
u32 pllp_wb0_override;
|
||||
u32 scratch24;
|
||||
u32 scratch25;
|
||||
u32 scratch26;
|
||||
u32 scratch27;
|
||||
u32 scratch28;
|
||||
u32 scratch29;
|
||||
u32 scratch30;
|
||||
u32 scratch31;
|
||||
u32 scratch32;
|
||||
u32 scratch33;
|
||||
u32 scratch34;
|
||||
u32 scratch35;
|
||||
u32 scratch36;
|
||||
u32 scratch37;
|
||||
u32 scratch38;
|
||||
u32 scratch39;
|
||||
u32 scratch40;
|
||||
u32 scratch41;
|
||||
u32 scratch42;
|
||||
u32 bondout_mirror[3];
|
||||
u32 sys_33v_en;
|
||||
u32 bondout_mirror_access;
|
||||
u32 gate;
|
||||
u32 wake2_mask;
|
||||
u32 wake2_lvl;
|
||||
u32 wake2_status;
|
||||
u32 sw_wake2_status;
|
||||
u32 auto_wake2_lvl_mask;
|
||||
u32 pg_mask_2;
|
||||
u32 pg_mask_ce1;
|
||||
u32 pg_mask_ce2;
|
||||
u32 pg_mask_ce3;
|
||||
u32 pwrgate_timer_ce[7];
|
||||
u32 pcx_edpd_cntrl;
|
||||
u32 osc_edpd_over;
|
||||
u32 clk_out_cntrl;
|
||||
u32 sata_pwrgt;
|
||||
u32 sensor_ctrl;
|
||||
u32 rst_status;
|
||||
u32 io_dpd_req;
|
||||
u32 io_dpd_status;
|
||||
u32 io_dpd2_req;
|
||||
u32 io_dpd2_status;
|
||||
u32 sel_dpd_tim;
|
||||
u32 vddp_sel;
|
||||
u32 ddr_cfg;
|
||||
u32 e_no_vttgen;
|
||||
u8 _rsv0[4];
|
||||
u32 pllm_wb0_override_freq;
|
||||
u32 test_pwrgate;
|
||||
u32 pwrgate_timer_mult;
|
||||
u32 dis_sel_dpd;
|
||||
u32 utmip_uhsic_triggers;
|
||||
u32 utmip_uhsic_saved_state;
|
||||
u32 utmip_pad_cfg;
|
||||
u32 utmip_term_pad_cfg;
|
||||
u32 utmip_uhsic_sleep_cfg;
|
||||
u32 utmip_uhsic_sleepwalk_cfg;
|
||||
u32 utmip_sleepwalk_p[3];
|
||||
u32 uhsic_sleepwalk_p0;
|
||||
u32 utmip_uhsic_status;
|
||||
u32 utmip_uhsic_fake;
|
||||
u32 bondout_mirror3[5 - 3];
|
||||
u32 secure_scratch6;
|
||||
u32 secure_scratch7;
|
||||
u32 scratch43;
|
||||
u32 scratch44;
|
||||
u32 scratch45;
|
||||
u32 scratch46;
|
||||
u32 scratch47;
|
||||
u32 scratch48;
|
||||
u32 scratch49;
|
||||
u32 scratch50;
|
||||
u32 scratch51;
|
||||
u32 scratch52;
|
||||
u32 scratch53;
|
||||
u32 scratch54;
|
||||
u32 scratch55;
|
||||
u32 scratch0_eco;
|
||||
u32 por_dpd_ctrl;
|
||||
u32 scratch2_eco;
|
||||
u32 utmip_uhsic_line_wakeup;
|
||||
u32 utmip_bias_master_cntrl;
|
||||
u32 utmip_master_config;
|
||||
u32 td_pwrgate_inter_part_timer;
|
||||
u32 utmip_uhsic2_triggers;
|
||||
u32 utmip_uhsic2_saved_state;
|
||||
u32 utmip_uhsic2_sleep_cfg;
|
||||
u32 utmip_uhsic2_sleepwalk_cfg;
|
||||
u32 uhsic2_sleepwalk_p1;
|
||||
u32 utmip_uhsic2_status;
|
||||
u32 utmip_uhsic2_fake;
|
||||
u32 utmip_uhsic2_line_wakeup;
|
||||
u32 utmip_master2_config;
|
||||
u32 utmip_uhsic_rpd_cfg;
|
||||
u32 pg_mask_ce0;
|
||||
u32 pg_mask3[5 - 3];
|
||||
u32 pllm_wb0_override2;
|
||||
u32 tsc_mult;
|
||||
u32 cpu_vsense_override;
|
||||
u32 glb_amap_cfg;
|
||||
u32 sticky_bits;
|
||||
u32 sec_disable2;
|
||||
u32 weak_bias;
|
||||
u32 reg_short;
|
||||
u32 pg_mask_andor;
|
||||
u8 _rsv1[0x2c];
|
||||
u32 secure_scratch8; /* offset 0x300 */
|
||||
u32 secure_scratch9;
|
||||
u32 secure_scratch10;
|
||||
u32 secure_scratch11;
|
||||
u32 secure_scratch12;
|
||||
u32 secure_scratch13;
|
||||
u32 secure_scratch14;
|
||||
u32 secure_scratch15;
|
||||
u32 secure_scratch16;
|
||||
u32 secure_scratch17;
|
||||
u32 secure_scratch18;
|
||||
u32 secure_scratch19;
|
||||
u32 secure_scratch20;
|
||||
u32 secure_scratch21;
|
||||
u32 secure_scratch22;
|
||||
u32 secure_scratch23;
|
||||
u32 secure_scratch24;
|
||||
u32 secure_scratch25;
|
||||
u32 secure_scratch26;
|
||||
u32 secure_scratch27;
|
||||
u32 secure_scratch28;
|
||||
u32 secure_scratch29;
|
||||
u32 secure_scratch30;
|
||||
u32 secure_scratch31;
|
||||
u32 secure_scratch32;
|
||||
u32 secure_scratch33;
|
||||
u32 secure_scratch34;
|
||||
u32 secure_scratch35;
|
||||
u32 secure_scratch36;
|
||||
u32 secure_scratch37;
|
||||
u32 secure_scratch38;
|
||||
u32 secure_scratch39;
|
||||
u32 secure_scratch40;
|
||||
u32 secure_scratch41;
|
||||
u32 secure_scratch42;
|
||||
u32 secure_scratch43;
|
||||
u32 secure_scratch44;
|
||||
u32 secure_scratch45;
|
||||
u32 secure_scratch46;
|
||||
u32 secure_scratch47;
|
||||
u32 secure_scratch48;
|
||||
u32 secure_scratch49;
|
||||
u32 secure_scratch50;
|
||||
u32 secure_scratch51;
|
||||
u32 secure_scratch52;
|
||||
u32 secure_scratch53;
|
||||
u32 secure_scratch54;
|
||||
u32 secure_scratch55;
|
||||
u32 secure_scratch56;
|
||||
u32 secure_scratch57;
|
||||
u32 secure_scratch58;
|
||||
u32 secure_scratch59;
|
||||
u32 secure_scratch60;
|
||||
u32 secure_scratch61;
|
||||
u32 secure_scratch62;
|
||||
u32 secure_scratch63;
|
||||
u32 secure_scratch64;
|
||||
u32 secure_scratch65;
|
||||
u32 secure_scratch66;
|
||||
u32 secure_scratch67;
|
||||
u32 secure_scratch68;
|
||||
u32 secure_scratch69;
|
||||
u32 secure_scratch70;
|
||||
u32 secure_scratch71;
|
||||
u32 secure_scratch72;
|
||||
u32 secure_scratch73;
|
||||
u32 secure_scratch74;
|
||||
u32 secure_scratch75;
|
||||
u32 secure_scratch76;
|
||||
u32 secure_scratch77;
|
||||
u32 secure_scratch78;
|
||||
u32 secure_scratch79;
|
||||
u32 _rsv0x420[8];
|
||||
u32 cntrl2; /* 0x440 */
|
||||
u32 _rsv0x444[2];
|
||||
u32 event_counter; /* 0x44C */
|
||||
u32 fuse_control;
|
||||
u32 scratch1_eco;
|
||||
u32 _rsv0x458[1];
|
||||
u32 io_dpd3_req; /* 0x45C */
|
||||
u32 io_dpd3_status;
|
||||
u32 io_dpd4_req;
|
||||
u32 io_dpd4_status;
|
||||
u32 _rsv0x46C[30];
|
||||
u32 ddr_cntrl; /* 0x4E4 */
|
||||
u32 _rsv0x4E8[70];
|
||||
u32 scratch56; /* 0x600 */
|
||||
u32 scratch57;
|
||||
u32 scratch58;
|
||||
u32 scratch59;
|
||||
u32 scratch60;
|
||||
u32 scratch61;
|
||||
u32 scratch62;
|
||||
u32 scratch63;
|
||||
u32 scratch64;
|
||||
u32 scratch65;
|
||||
u32 scratch66;
|
||||
u32 scratch67;
|
||||
u32 scratch68;
|
||||
u32 scratch69;
|
||||
u32 scratch70;
|
||||
u32 scratch71;
|
||||
u32 scratch72;
|
||||
u32 scratch73;
|
||||
u32 scratch74;
|
||||
u32 scratch75;
|
||||
u32 scratch76;
|
||||
u32 scratch77;
|
||||
u32 scratch78;
|
||||
u32 scratch79;
|
||||
u32 scratch80;
|
||||
u32 scratch81;
|
||||
u32 scratch82;
|
||||
u32 scratch83;
|
||||
u32 scratch84;
|
||||
u32 scratch85;
|
||||
u32 scratch86;
|
||||
u32 scratch87;
|
||||
u32 scratch88;
|
||||
u32 scratch89;
|
||||
u32 scratch90;
|
||||
u32 scratch91;
|
||||
u32 scratch92;
|
||||
u32 scratch93;
|
||||
u32 scratch94;
|
||||
u32 scratch95;
|
||||
u32 scratch96;
|
||||
u32 scratch97;
|
||||
u32 scratch98;
|
||||
u32 scratch99;
|
||||
u32 scratch100;
|
||||
u32 scratch101;
|
||||
u32 scratch102;
|
||||
u32 scratch103;
|
||||
u32 scratch104;
|
||||
u32 scratch105;
|
||||
u32 scratch106;
|
||||
u32 scratch107;
|
||||
u32 scratch108;
|
||||
u32 scratch109;
|
||||
u32 scratch110;
|
||||
u32 scratch111;
|
||||
u32 scratch112;
|
||||
u32 scratch113;
|
||||
u32 scratch114;
|
||||
u32 scratch115;
|
||||
u32 scratch116;
|
||||
u32 scratch117;
|
||||
u32 scratch118;
|
||||
u32 scratch119;
|
||||
u32 scratch120; /* 0x700 */
|
||||
u32 scratch121;
|
||||
u32 scratch122;
|
||||
u32 scratch123;
|
||||
u32 scratch124;
|
||||
u32 scratch125;
|
||||
u32 scratch126;
|
||||
u32 scratch127;
|
||||
u32 scratch128;
|
||||
u32 scratch129;
|
||||
u32 scratch130;
|
||||
u32 scratch131;
|
||||
u32 scratch132;
|
||||
u32 scratch133;
|
||||
u32 scratch134;
|
||||
u32 scratch135;
|
||||
u32 scratch136;
|
||||
u32 scratch137;
|
||||
u32 scratch138;
|
||||
u32 scratch139;
|
||||
u32 scratch140;
|
||||
u32 scratch141;
|
||||
u32 scratch142;
|
||||
u32 scratch143;
|
||||
u32 scratch144;
|
||||
u32 scratch145;
|
||||
u32 scratch146;
|
||||
u32 scratch147;
|
||||
u32 scratch148;
|
||||
u32 scratch149;
|
||||
u32 scratch150;
|
||||
u32 scratch151;
|
||||
u32 scratch152;
|
||||
u32 scratch153;
|
||||
u32 scratch154;
|
||||
u32 scratch155;
|
||||
u32 scratch156;
|
||||
u32 scratch157;
|
||||
u32 scratch158;
|
||||
u32 scratch159;
|
||||
u32 scratch160;
|
||||
u32 scratch161;
|
||||
u32 scratch162;
|
||||
u32 scratch163;
|
||||
u32 scratch164;
|
||||
u32 scratch165;
|
||||
u32 scratch166;
|
||||
u32 scratch167;
|
||||
u32 scratch168;
|
||||
u32 scratch169;
|
||||
u32 scratch170;
|
||||
u32 scratch171;
|
||||
u32 scratch172;
|
||||
u32 scratch173;
|
||||
u32 scratch174;
|
||||
u32 scratch175;
|
||||
u32 scratch176;
|
||||
u32 scratch177;
|
||||
u32 scratch178;
|
||||
u32 scratch179;
|
||||
u32 scratch180;
|
||||
u32 scratch181;
|
||||
u32 scratch182;
|
||||
u32 scratch183;
|
||||
u32 scratch184;
|
||||
u32 scratch185;
|
||||
u32 scratch186;
|
||||
u32 scratch187;
|
||||
u32 scratch188;
|
||||
u32 scratch189;
|
||||
u32 scratch190;
|
||||
u32 scratch191;
|
||||
u32 scratch192;
|
||||
u32 scratch193;
|
||||
u32 scratch194;
|
||||
u32 scratch195;
|
||||
u32 scratch196;
|
||||
u32 scratch197;
|
||||
u32 scratch198;
|
||||
u32 scratch199;
|
||||
u32 scratch200;
|
||||
u32 scratch201;
|
||||
u32 scratch202;
|
||||
u32 scratch203;
|
||||
u32 scratch204;
|
||||
u32 scratch205;
|
||||
u32 scratch206;
|
||||
u32 scratch207;
|
||||
u32 scratch208;
|
||||
u32 scratch209;
|
||||
u32 scratch210;
|
||||
u32 scratch211;
|
||||
u32 scratch212;
|
||||
u32 scratch213;
|
||||
u32 scratch214;
|
||||
u32 scratch215;
|
||||
u32 scratch216;
|
||||
u32 scratch217;
|
||||
u32 scratch218;
|
||||
u32 scratch219;
|
||||
u32 scratch220;
|
||||
u32 scratch221;
|
||||
u32 scratch222;
|
||||
u32 scratch223;
|
||||
u32 scratch224;
|
||||
u32 scratch225;
|
||||
u32 scratch226;
|
||||
u32 scratch227;
|
||||
u32 scratch228;
|
||||
u32 scratch229;
|
||||
u32 scratch230;
|
||||
u32 scratch231;
|
||||
u32 scratch232;
|
||||
u32 scratch233;
|
||||
u32 scratch234;
|
||||
u32 scratch235;
|
||||
u32 scratch236;
|
||||
u32 scratch237;
|
||||
u32 scratch238;
|
||||
u32 scratch239;
|
||||
u32 scratch240;
|
||||
u32 scratch241;
|
||||
u32 scratch242;
|
||||
u32 scratch243;
|
||||
u32 scratch244;
|
||||
u32 scratch245;
|
||||
u32 scratch246;
|
||||
u32 scratch247;
|
||||
u32 scratch248;
|
||||
u32 scratch249;
|
||||
u32 scratch250;
|
||||
u32 scratch251;
|
||||
u32 scratch252;
|
||||
u32 scratch253;
|
||||
u32 scratch254;
|
||||
u32 scratch255;
|
||||
u32 scratch256;
|
||||
u32 scratch257;
|
||||
u32 scratch258;
|
||||
u32 scratch259;
|
||||
u32 scratch260;
|
||||
u32 scratch261;
|
||||
u32 scratch262;
|
||||
u32 scratch263;
|
||||
u32 scratch264;
|
||||
u32 scratch265;
|
||||
u32 scratch266;
|
||||
u32 scratch267;
|
||||
u32 scratch268;
|
||||
u32 scratch269;
|
||||
u32 scratch270;
|
||||
u32 scratch271;
|
||||
u32 scratch272;
|
||||
u32 scratch273;
|
||||
u32 scratch274;
|
||||
u32 scratch275;
|
||||
u32 scratch276;
|
||||
u32 scratch277;
|
||||
u32 scratch278;
|
||||
u32 scratch279;
|
||||
u32 scratch280;
|
||||
u32 scratch281;
|
||||
u32 scratch282;
|
||||
u32 scratch283;
|
||||
u32 scratch284;
|
||||
u32 scratch285;
|
||||
u32 scratch286;
|
||||
u32 scratch287;
|
||||
u32 scratch288;
|
||||
u32 scratch289;
|
||||
u32 scratch290;
|
||||
u32 scratch291;
|
||||
u32 scratch292;
|
||||
u32 scratch293;
|
||||
u32 scratch294;
|
||||
u32 scratch295;
|
||||
u32 scratch296;
|
||||
u32 scratch297;
|
||||
u32 scratch298;
|
||||
u32 scratch299; /* 0x9CC */
|
||||
u32 _rsv0x9D0[50];
|
||||
u32 secure_scratch80; /* 0xa98 */
|
||||
u32 secure_scratch81;
|
||||
u32 secure_scratch82;
|
||||
u32 secure_scratch83;
|
||||
u32 secure_scratch84;
|
||||
u32 secure_scratch85;
|
||||
u32 secure_scratch86;
|
||||
u32 secure_scratch87;
|
||||
u32 secure_scratch88;
|
||||
u32 secure_scratch89;
|
||||
u32 secure_scratch90;
|
||||
u32 secure_scratch91;
|
||||
u32 secure_scratch92;
|
||||
u32 secure_scratch93;
|
||||
u32 secure_scratch94;
|
||||
u32 secure_scratch95;
|
||||
u32 secure_scratch96;
|
||||
u32 secure_scratch97;
|
||||
u32 secure_scratch98;
|
||||
u32 secure_scratch99;
|
||||
u32 secure_scratch100;
|
||||
u32 secure_scratch101;
|
||||
u32 secure_scratch102;
|
||||
u32 secure_scratch103;
|
||||
u32 secure_scratch104;
|
||||
u32 secure_scratch105;
|
||||
u32 secure_scratch106;
|
||||
u32 secure_scratch107;
|
||||
u32 secure_scratch108;
|
||||
u32 secure_scratch109;
|
||||
u32 secure_scratch110;
|
||||
u32 secure_scratch111;
|
||||
u32 secure_scratch112;
|
||||
u32 secure_scratch113;
|
||||
u32 secure_scratch114;
|
||||
u32 secure_scratch115;
|
||||
u32 secure_scratch116;
|
||||
u32 secure_scratch117;
|
||||
u32 secure_scratch118;
|
||||
u32 secure_scratch119;
|
||||
};
|
||||
|
||||
#endif /* _TEGRA210_PMC_H_ */
|
121
emummc/source/soc/t210.h
Normal file
121
emummc/source/soc/t210.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _T210_H_
|
||||
#define _T210_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
intptr_t QueryIoMapping(u64 addr, u64 size);
|
||||
|
||||
#define TMR_BASE 0x60005000
|
||||
#define CLOCK_BASE 0x60006000
|
||||
#define GPIO_BASE 0x6000D000
|
||||
#define GPIO_1_BASE (GPIO_BASE)
|
||||
#define GPIO_2_BASE (GPIO_BASE + 0x100)
|
||||
#define GPIO_3_BASE (GPIO_BASE + 0x200)
|
||||
#define GPIO_4_BASE (GPIO_BASE + 0x300)
|
||||
#define GPIO_5_BASE (GPIO_BASE + 0x400)
|
||||
#define GPIO_6_BASE (GPIO_BASE + 0x500)
|
||||
#define GPIO_7_BASE (GPIO_BASE + 0x600)
|
||||
#define GPIO_8_BASE (GPIO_BASE + 0x700)
|
||||
#define APB_MISC_BASE 0x70000000
|
||||
#define PINMUX_AUX_BASE 0x70003000
|
||||
#define PWM_BASE 0x7000A000
|
||||
#define RTC_BASE 0x7000E000
|
||||
#define PMC_BASE 0x7000E400
|
||||
|
||||
#define _REG(base, off) *(vu32 *)(QueryIoMapping((u64)base, 0) + (off))
|
||||
#define _REG_IO(base, off, size) *(vu32 *)(QueryIoMapping((u64)base, size) + (off))
|
||||
|
||||
#define RTC(off) _REG_IO(RTC_BASE, off, 0x4000)
|
||||
#define TMR(off) _REG_IO(TMR_BASE, off, 0x3FF)
|
||||
#define CLOCK(off) _REG_IO(CLOCK_BASE, off, 0x1000)
|
||||
|
||||
#define PMC(off) _REG_IO(PMC_BASE, off, 0x1000) // ??????????
|
||||
|
||||
#define APB_MISC(off) _REG_IO(APB_MISC_BASE, off, 0x4000)
|
||||
#define PINMUX_AUX(off) _REG_IO(APB_MISC_BASE, off + (PINMUX_AUX_BASE - APB_MISC_BASE), 0x4000)
|
||||
|
||||
#define GPIO(off) _REG_IO(GPIO_BASE, off, 0x1000)
|
||||
#define GPIO_1(off) _REG_IO(GPIO_BASE, off + (GPIO_1_BASE - GPIO_BASE), 0x1000)
|
||||
#define GPIO_2(off) _REG_IO(GPIO_BASE, off + (GPIO_2_BASE - GPIO_BASE), 0x1000)
|
||||
#define GPIO_3(off) _REG_IO(GPIO_BASE, off + (GPIO_3_BASE - GPIO_BASE), 0x1000)
|
||||
#define GPIO_4(off) _REG_IO(GPIO_BASE, off + (GPIO_4_BASE - GPIO_BASE), 0x1000)
|
||||
#define GPIO_5(off) _REG_IO(GPIO_BASE, off + (GPIO_5_BASE - GPIO_BASE), 0x1000)
|
||||
#define GPIO_6(off) _REG_IO(GPIO_BASE, off + (GPIO_6_BASE - GPIO_BASE), 0x1000)
|
||||
#define GPIO_7(off) _REG_IO(GPIO_BASE, off + (GPIO_7_BASE - GPIO_BASE), 0x1000)
|
||||
#define GPIO_8(off) _REG_IO(GPIO_BASE, off + (GPIO_8_BASE - GPIO_BASE), 0x1000)
|
||||
|
||||
#define HOST1X(off) _REG(HOST1X_BASE, off)
|
||||
#define BPMP_CACHE_CTRL(off) _REG(BPMP_CACHE_BASE, off)
|
||||
#define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off)
|
||||
#define DSI(off) _REG(DSI_BASE, off)
|
||||
#define VIC(off) _REG(VIC_BASE, off)
|
||||
#define TSEC(off) _REG(TSEC_BASE, off)
|
||||
#define SOR1(off) _REG(SOR1_BASE, off)
|
||||
#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off)
|
||||
#define SYSREG(off) _REG(SYSREG_BASE, off)
|
||||
#define SB(off) _REG(SB_BASE, off)
|
||||
#define EXCP_VEC(off) _REG(EXCP_VEC_BASE, off)
|
||||
#define PWM(off) _REG(PWM_BASE, off)
|
||||
#define SYSCTR0(off) _REG(SYSCTR0_BASE, off)
|
||||
#define FUSE(off) _REG(FUSE_BASE, off)
|
||||
#define KFUSE(off) _REG(KFUSE_BASE, off)
|
||||
#define SE(off) _REG(SE_BASE, off)
|
||||
#define MC(off) _REG(MC_BASE, off)
|
||||
#define EMC(off) _REG(EMC_BASE, off)
|
||||
#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off)
|
||||
#define I2S(off) _REG(I2S_BASE, off)
|
||||
#define CL_DVFS(off) _REG(CL_DVFS_BASE, off)
|
||||
#define TEST_REG(off) _REG(0x0, off)
|
||||
|
||||
/*! Misc registers. */
|
||||
#define APB_MISC_PP_STRAPPING_OPT_A 0x08
|
||||
#define APB_MISC_PP_PINMUX_GLOBAL 0x40
|
||||
#define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34
|
||||
#define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98
|
||||
#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4
|
||||
#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64
|
||||
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68
|
||||
|
||||
/*! System registers. */
|
||||
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
|
||||
#define AHB_AHB_SPARE_REG 0x110
|
||||
|
||||
/*! RTC registers. */
|
||||
#define APBDEV_RTC_SECONDS 0x8
|
||||
#define APBDEV_RTC_SHADOW_SECONDS 0xC
|
||||
#define APBDEV_RTC_MILLI_SECONDS 0x10
|
||||
|
||||
/*! TMR registers. */
|
||||
#define TIMERUS_CNTR_1US (0x10 + 0x0)
|
||||
#define TIMERUS_USEC_CFG (0x10 + 0x4)
|
||||
#define TIMER_TMR9_TMR_PTV 0x80
|
||||
#define TIMER_EN (1 << 31)
|
||||
#define TIMER_PER_EN (1 << 30)
|
||||
#define TIMER_WDT4_CONFIG (0x100 + 0x80)
|
||||
#define TIMER_SRC(TMR) (TMR & 0xF)
|
||||
#define TIMER_PER(PER) ((PER & 0xFF) << 4)
|
||||
#define TIMER_SYSRESET_EN (1 << 14)
|
||||
#define TIMER_PMCRESET_EN (1 << 15)
|
||||
#define TIMER_WDT4_COMMAND (0x108 + 0x80)
|
||||
#define TIMER_START_CNT (1 << 0)
|
||||
#define TIMER_CNT_DISABLE (1 << 1)
|
||||
#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80)
|
||||
#define TIMER_MAGIC_PTRN 0xC45A
|
||||
|
||||
#endif
|
27
emummc/source/utils/fatal.c
Normal file
27
emummc/source/utils/fatal.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "fatal.h"
|
||||
|
||||
void __attribute__((noreturn)) fatal_abort(enum FatalReason abortReason)
|
||||
{
|
||||
// Reboot to RCM
|
||||
smcRebootToRcm();
|
||||
|
||||
while(true)
|
||||
; // Should never be reached
|
||||
}
|
34
emummc/source/utils/fatal.h
Normal file
34
emummc/source/utils/fatal.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../nx/smc.h"
|
||||
|
||||
enum FatalReason {
|
||||
Fatal_InitMMC = 0,
|
||||
Fatal_InitSD,
|
||||
Fatal_InvalidAccessor,
|
||||
Fatal_ReadNoAccessor,
|
||||
Fatal_WriteNoAccessor,
|
||||
Fatal_IoMapping,
|
||||
Fatal_UnknownVersion,
|
||||
Fatal_BadResult,
|
||||
Fatal_GetConfig,
|
||||
Fatal_Max
|
||||
};
|
||||
|
||||
void __attribute__((noreturn)) fatal_abort(enum FatalReason abortReason);
|
97
emummc/source/utils/types.h
Normal file
97
emummc/source/utils/types.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TYPES_H_
|
||||
#define _TYPES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#define OFFSET_OF(t, m) ((u32)&((t *)NULL)->m)
|
||||
#define CONTAINER_OF(mp, t, mn) ((t *)((u32)mp - OFFSET_OF(t, mn)))
|
||||
|
||||
/// Creates a bitmask from a bit number.
|
||||
#ifndef BIT
|
||||
#define BIT(n) (1U<<(n))
|
||||
#endif
|
||||
|
||||
typedef signed char s8;
|
||||
typedef short s16;
|
||||
typedef short SHORT;
|
||||
typedef int s32;
|
||||
typedef int INT;
|
||||
typedef long LONG;
|
||||
typedef long long int s64;
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned long long QWORD;
|
||||
typedef unsigned long long int u64;
|
||||
typedef volatile unsigned char vu8;
|
||||
typedef volatile unsigned short vu16;
|
||||
typedef volatile unsigned int vu32;
|
||||
|
||||
typedef u32 Handle; ///< Kernel object handle.
|
||||
typedef u32 Result; ///< Function error code result type.
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef int bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define BOOT_CFG_AUTOBOOT_EN (1 << 0)
|
||||
#define BOOT_CFG_FROM_LAUNCH (1 << 1)
|
||||
#define BOOT_CFG_SEPT_RUN (1 << 7)
|
||||
|
||||
#define EXTRA_CFG_KEYS (1 << 0)
|
||||
#define EXTRA_CFG_PAYLOAD (1 << 1)
|
||||
#define EXTRA_CFG_MODULE (1 << 2)
|
||||
|
||||
typedef struct __attribute__((__packed__)) _boot_cfg_t
|
||||
{
|
||||
u8 boot_cfg;
|
||||
u8 autoboot;
|
||||
u8 autoboot_list;
|
||||
u8 extra_cfg;
|
||||
u8 rsvd[128];
|
||||
} boot_cfg_t;
|
||||
|
||||
typedef struct __attribute__((__packed__)) _ipl_ver_meta_t
|
||||
{
|
||||
u32 magic;
|
||||
u32 version;
|
||||
u16 rsvd0;
|
||||
u16 rsvd1;
|
||||
} ipl_ver_meta_t;
|
||||
|
||||
typedef struct __attribute__((__packed__)) _reloc_meta_t
|
||||
{
|
||||
u32 start;
|
||||
u32 stack;
|
||||
u32 end;
|
||||
u32 ep;
|
||||
} reloc_meta_t;
|
||||
|
||||
#endif
|
110
emummc/source/utils/util.c
Normal file
110
emummc/source/utils/util.c
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (C) 2019 M4xw
|
||||
* Copyright (c) 2019 Atmosphere-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "util.h"
|
||||
#include "fatal.h"
|
||||
#include "types.h"
|
||||
#include "../nx/counter.h"
|
||||
#include "../nx/svc.h"
|
||||
#include "../soc/t210.h"
|
||||
|
||||
typedef struct _io_mapping_t
|
||||
{
|
||||
u64 phys;
|
||||
u64 virt;
|
||||
u64 size;
|
||||
} io_mapping_t;
|
||||
static io_mapping_t io_mapping_list[10] = {0}; // Max 10 Mappings
|
||||
#define IO_MAPPING_COUNT (sizeof(io_mapping_list) / sizeof(io_mapping_t))
|
||||
|
||||
static inline uintptr_t _GetIoMapping(u64 io_addr, u64 io_size)
|
||||
{
|
||||
u64 vaddr;
|
||||
u64 aligned_addr = (io_addr & ~0xFFFul);
|
||||
u64 aligned_size = io_size + (io_addr - aligned_addr);
|
||||
if (svcQueryIoMapping(&vaddr, aligned_addr, aligned_size) != 0) {
|
||||
fatal_abort(Fatal_IoMapping);
|
||||
}
|
||||
return (uintptr_t)(vaddr + (io_addr - aligned_addr));
|
||||
}
|
||||
|
||||
intptr_t QueryIoMapping(u64 addr, u64 size)
|
||||
{
|
||||
for (int i = 0; i < IO_MAPPING_COUNT; i++)
|
||||
{
|
||||
if (io_mapping_list[i].phys == addr && io_mapping_list[i].size == size)
|
||||
{
|
||||
return io_mapping_list[i].virt;
|
||||
}
|
||||
}
|
||||
|
||||
u64 ioMap = _GetIoMapping(addr, size);
|
||||
|
||||
for (int i = 0; i < IO_MAPPING_COUNT; i++)
|
||||
{
|
||||
if (io_mapping_list[i].phys == 0 && io_mapping_list[i].virt == 0 && io_mapping_list[i].size == 0) // First empty
|
||||
{
|
||||
io_mapping_list[i].virt = ioMap;
|
||||
io_mapping_list[i].phys = addr;
|
||||
io_mapping_list[i].size = size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (intptr_t)ioMap;
|
||||
}
|
||||
|
||||
u64 get_tmr_s()
|
||||
{
|
||||
return armTicksToNs(armGetSystemTick()) / 1e+9;
|
||||
}
|
||||
|
||||
u64 get_tmr_ms()
|
||||
{
|
||||
return armTicksToNs(armGetSystemTick()) / 1000000;
|
||||
}
|
||||
|
||||
u64 get_tmr_us()
|
||||
{
|
||||
return armTicksToNs(armGetSystemTick()) / 1000;
|
||||
}
|
||||
|
||||
// TODO: Figure if Sleep or Busy loop
|
||||
void msleep(u64 milliseconds)
|
||||
{
|
||||
u64 now = get_tmr_ms();
|
||||
while (get_tmr_ms() - now < milliseconds)
|
||||
;
|
||||
//svcSleepThread(1000000 * milliseconds);
|
||||
}
|
||||
|
||||
// TODO: Figure if Sleep or Busy loop
|
||||
void usleep(u64 microseconds)
|
||||
{
|
||||
u64 now = get_tmr_us();
|
||||
while (get_tmr_us() - now < microseconds)
|
||||
;
|
||||
//svcSleepThread(1000 * microseconds);
|
||||
}
|
||||
|
||||
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops)
|
||||
{
|
||||
for (u32 i = 0; i < num_ops; i++)
|
||||
base[ops[i].off] = ops[i].val;
|
||||
}
|
40
emummc/source/utils/util.h
Normal file
40
emummc/source/utils/util.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
intptr_t QueryIoMapping(u64 addr, u64 size);
|
||||
#define byte_swap_32(num) ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
|
||||
((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000)
|
||||
|
||||
typedef struct _cfg_op_t
|
||||
{
|
||||
u32 off;
|
||||
u32 val;
|
||||
} cfg_op_t;
|
||||
|
||||
u64 get_tmr_us();
|
||||
u64 get_tmr_ms();
|
||||
u64 get_tmr_s();
|
||||
void usleep(u64 ticks);
|
||||
void msleep(u64 milliseconds);
|
||||
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
|
||||
|
||||
#endif
|
36
emummc/tools/fs_ida_nintendo_folder_xref_formatter.au3
Normal file
36
emummc/tools/fs_ida_nintendo_folder_xref_formatter.au3
Normal file
|
@ -0,0 +1,36 @@
|
|||
ParseClipboard()
|
||||
|
||||
Func FormatLineData($sLineData)
|
||||
Local $lineData = StringReplace($sLineData, @TAB, " ")
|
||||
Local $isADRP = false
|
||||
$lineData = StringReplace($lineData, "Up o sub_71000" , "0x")
|
||||
$isADRP = StringInStr($lineData, "ADRP")
|
||||
|
||||
Local $targetRegister = StringSplit(StringSplit($lineData, "X")[2], ",")[1]
|
||||
$lineData = StringSplit($lineData, " ")[1]
|
||||
$lineDataAddr = StringSplit($lineData, "+")[1]
|
||||
$lineDataAddition = StringSplit($lineData, "+")[2]
|
||||
|
||||
$lineDataAddr = StringReplace($lineDataAddr, "0x" , "")
|
||||
$lineDataAddition = StringReplace($lineDataAddition, "0x" , "")
|
||||
|
||||
If $isADRP Then
|
||||
$lineData = "0x" & Hex(Dec($lineDataAddr) + Dec($lineDataAddition))
|
||||
Else
|
||||
Return ""
|
||||
EndIf
|
||||
|
||||
Return "{.opcode_reg = " & $targetRegister & ", .adrp_offset = " & $lineData & "}, \" & @LF
|
||||
EndFunc
|
||||
|
||||
Func ParseClipboard()
|
||||
Local $sData = ClipGet()
|
||||
Local $oData = ""
|
||||
Local $sLineData = StringSplit(StringReplace($sData, @CRLF, @LF), @LF)
|
||||
For $i = 2 to UBound($sLineData) - 2
|
||||
Local $lineData = FormatLineData($sLineData[$i])
|
||||
;ConsoleWrite($lineData)
|
||||
$oData = $oData & $lineData
|
||||
Next
|
||||
ClipPut($oData)
|
||||
EndFunc
|
54
emummc/tools/kip1converter.py
Normal file
54
emummc/tools/kip1converter.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
# Modified kip1 conversion script, originally by jakibaki
|
||||
# Used for dev purposes, will be replaced in the future
|
||||
|
||||
from struct import pack, unpack
|
||||
from sys import argv
|
||||
|
||||
f = open(argv[1], "rb")
|
||||
|
||||
header_start = f.read(0x20)
|
||||
|
||||
section_names = [".text", ".rodata", ".data", ".bss"]
|
||||
|
||||
sections = []
|
||||
for i in range(6):
|
||||
section_bytes = f.read(0x10)
|
||||
section = {}
|
||||
|
||||
if i < len(section_names):
|
||||
section["Name"] = section_names[i]
|
||||
|
||||
section["OutOffset"], section["DecompressedSize"], section["CompressedSize"], section["Attribute"] = unpack(
|
||||
"IIII", section_bytes)
|
||||
sections.append(section)
|
||||
print(section)
|
||||
|
||||
assert (sections[3]["OutOffset"] + sections[3]["DecompressedSize"]) % 0x1000 == 0
|
||||
|
||||
kernel_caps = []
|
||||
for i in range(0x20):
|
||||
val, = unpack("I", f.read(4))
|
||||
kernel_caps.append(val)
|
||||
|
||||
f.seek(0x100)
|
||||
|
||||
for i in range(3):
|
||||
section = sections[i]
|
||||
section["Buffer"] = f.read(section["DecompressedSize"])
|
||||
print(f.read())
|
||||
|
||||
f.close()
|
||||
|
||||
f = open(argv[2], "wb")
|
||||
|
||||
for i in range(3):
|
||||
section = sections[i]
|
||||
f.seek(section["OutOffset"])
|
||||
f.write(section["Buffer"])
|
||||
|
||||
f.seek(sections[3]["OutOffset"])
|
||||
f.write(b'\0' * sections[3]["DecompressedSize"])
|
||||
|
||||
caps = open("emummc.caps", "wb")
|
||||
for i in range(0x20):
|
||||
caps.write(pack("I", kernel_caps[i]))
|
Loading…
Reference in a new issue